summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Repository.mk4
-rw-r--r--avmedia/Library_avmedia.mk1
-rw-r--r--avmedia/Library_avmediaogl.mk1
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx2
-rw-r--r--canvas/Library_oglcanvas.mk1
-rw-r--r--chart2/Library_chartcontroller.mk1
-rw-r--r--chart2/Library_chartcore.mk2
-rw-r--r--chart2/Library_chartopengl.mk1
-rwxr-xr-xchart2/source/view/main/GL3DRenderer.cxx3
-rw-r--r--include/vcl/opengl/OpenGLContext.hxx36
-rw-r--r--include/vcl/opengl/OpenGLHelper.hxx16
-rw-r--r--include/vcl/outdev.hxx2
-rw-r--r--officecfg/registry/data/org/openoffice/Office/Common.xcu8
-rw-r--r--officecfg/registry/data/org/openoffice/Setup.xcu2
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Common.xcs79
-rw-r--r--sc/CppunitTest_sc_ucalc.mk1
-rw-r--r--sc/Library_sc.mk1
-rw-r--r--sc/workben/opencl/platform_detect.cxx14
-rw-r--r--shell/source/backends/gconfbe/gconfaccess.cxx16
-rw-r--r--shell/source/backends/gconfbe/gconfaccess.hxx2
-rw-r--r--slideshow/Library_OGLTrans.mk1
-rw-r--r--slideshow/Library_slideshow.mk1
-rw-r--r--slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx6
-rw-r--r--solenv/gbuild/extensions/pre_MergedLibsList.mk1
-rw-r--r--svx/Library_svxcore.mk1
-rw-r--r--vcl/Executable_icontest.mk1
-rw-r--r--vcl/Executable_outdevgrind.mk39
-rw-r--r--vcl/Executable_vcldemo.mk4
-rw-r--r--vcl/Library_vcl.mk35
-rw-r--r--vcl/Library_vclopengl.mk88
-rw-r--r--vcl/Library_vclplug_gen.mk13
-rw-r--r--vcl/Module_vcl.mk9
-rw-r--r--vcl/Package_opengl.mk24
-rw-r--r--vcl/headless/svpbmp.cxx5
-rw-r--r--vcl/inc/cairotextrender.hxx129
-rw-r--r--vcl/inc/generic/genpspgraphics.h2
-rw-r--r--vcl/inc/generic/glyphcache.hxx1
-rw-r--r--vcl/inc/graphite_serverfont.hxx2
-rw-r--r--vcl/inc/headless/svpbmp.hxx2
-rw-r--r--vcl/inc/headless/svpgdi.hxx2
-rw-r--r--vcl/inc/impbmp.hxx10
-rw-r--r--vcl/inc/opengl/bmpop.hxx35
-rw-r--r--vcl/inc/opengl/salbmp.hxx120
-rw-r--r--vcl/inc/opengl/texture.hxx54
-rw-r--r--vcl/inc/opengl/win/gdiimpl.hxx36
-rw-r--r--vcl/inc/opengl/x11/gdiimpl.hxx42
-rw-r--r--vcl/inc/openglgdiimpl.hxx259
-rw-r--r--vcl/inc/quartz/salbmp.h2
-rw-r--r--vcl/inc/quartz/salgdi.h2
-rw-r--r--vcl/inc/salbmp.hxx2
-rw-r--r--vcl/inc/salgdi.hxx2
-rw-r--r--vcl/inc/salgdiimpl.hxx210
-rw-r--r--vcl/inc/textrender.hxx81
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx5
-rw-r--r--vcl/inc/unx/gtk/gtkgdi.hxx5
-rw-r--r--vcl/inc/unx/pixmap.hxx46
-rw-r--r--vcl/inc/unx/salbmp.h2
-rw-r--r--vcl/inc/unx/salframe.h5
-rw-r--r--vcl/inc/unx/salgdi.h121
-rw-r--r--vcl/inc/unx/x11/x11gdiimpl.h27
-rw-r--r--vcl/inc/unx/x11windowprovider.hxx28
-rw-r--r--vcl/inc/win/salbmp.h2
-rw-r--r--vcl/inc/win/salgdi.h69
-rw-r--r--vcl/inc/win/svsys.h3
-rw-r--r--vcl/opengl/README.deprecated (renamed from chart2/opengl/README.deprecated)0
-rw-r--r--vcl/opengl/convolutionFragmentShader.glsl28
-rw-r--r--vcl/opengl/gdiimpl.cxx1000
-rw-r--r--vcl/opengl/maskFragmentShader.glsl21
-rw-r--r--vcl/opengl/maskVertexShader.glsl19
-rw-r--r--vcl/opengl/maskedTextureFragmentShader.glsl23
-rw-r--r--vcl/opengl/maskedTextureVertexShader.glsl19
-rw-r--r--vcl/opengl/salbmp.cxx513
-rw-r--r--vcl/opengl/scale.cxx308
-rw-r--r--vcl/opengl/solidFragmentShader.glsl17
-rw-r--r--vcl/opengl/solidVertexShader.glsl16
-rw-r--r--vcl/opengl/texture.cxx144
-rw-r--r--vcl/opengl/textureFragmentShader.glsl18
-rw-r--r--vcl/opengl/textureVertexShader.glsl19
-rw-r--r--vcl/opengl/win/gdiimpl.cxx65
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx139
-rw-r--r--vcl/quartz/salbmp.cxx5
-rw-r--r--vcl/source/gdi/bitmap.cxx3
-rw-r--r--vcl/source/gdi/bitmap3.cxx20
-rw-r--r--vcl/source/gdi/impbmp.cxx12
-rw-r--r--vcl/source/gdi/salgdiimpl.cxx26
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx434
-rw-r--r--vcl/source/opengl/OpenGLHelper.cxx83
-rw-r--r--vcl/source/outdev/bitmap.cxx3
-rw-r--r--vcl/source/outdev/outdev.cxx7
-rw-r--r--vcl/source/outdev/polygon.cxx2
-rw-r--r--vcl/source/window/paint.cxx2
-rw-r--r--vcl/unx/generic/app/saldisp.cxx8
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx660
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx1850
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.hxx278
-rw-r--r--vcl/unx/generic/gdi/openglx11cairotextrender.cxx50
-rw-r--r--vcl/unx/generic/gdi/openglx11cairotextrender.hxx26
-rw-r--r--vcl/unx/generic/gdi/pixmap.cxx49
-rw-r--r--vcl/unx/generic/gdi/salbmp.cxx16
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx913
-rw-r--r--vcl/unx/generic/gdi/salgdi2.cxx772
-rw-r--r--vcl/unx/generic/gdi/salgdi3.cxx590
-rw-r--r--vcl/unx/generic/gdi/salvd.cxx6
-rw-r--r--vcl/unx/generic/gdi/x11cairotextrender.cxx129
-rw-r--r--vcl/unx/generic/gdi/x11cairotextrender.hxx50
-rw-r--r--vcl/unx/generic/gdi/x11windowprovider.cxx16
-rw-r--r--vcl/unx/generic/window/salframe.cxx5
-rw-r--r--vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx236
-rw-r--r--vcl/unx/gtk/window/gtksalframe.cxx5
-rw-r--r--vcl/win/source/gdi/gdiimpl.cxx2371
-rw-r--r--vcl/win/source/gdi/gdiimpl.hxx218
-rw-r--r--vcl/win/source/gdi/salbmp.cxx5
-rw-r--r--vcl/win/source/gdi/salgdi.cxx1086
-rw-r--r--vcl/win/source/gdi/salgdi2.cxx728
-rw-r--r--vcl/win/source/gdi/salgdi_gdiplus.cxx469
-rw-r--r--vcl/win/source/gdi/salprn.cxx21
-rw-r--r--vcl/win/source/gdi/salvd.cxx19
-rw-r--r--vcl/win/source/window/salframe.cxx78
-rw-r--r--vcl/workben/icontest.cxx218
-rw-r--r--vcl/workben/outdevgrind.cxx103
-rw-r--r--vcl/workben/vcldemo.cxx418
121 files changed, 10808 insertions, 5258 deletions
diff --git a/Repository.mk b/Repository.mk
index fd05e114bc8d..3d3e35af673b 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -68,7 +68,8 @@ $(eval $(call gb_Helper_register_executables,NONE, \
svpclient \
pixelctl ) \
$(if $(and $(ENABLE_GTK), $(filter LINUX,$(OS))), tilebench) \
- $(if $(filter LINUX MACOSX WNT,$(OS)),icontest) \
+ $(if $(filter LINUX MACOSX WNT,$(OS)),icontest \
+ outdevgrind) \
vcldemo \
tiledrendering \
$(if $(and $(ENABLE_GTK), $(filter LINUX,$(OS))), gtktiledviewer) \
@@ -452,7 +453,6 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
) \
vcl \
vclcanvas \
- vclopengl \
$(if $(and $(filter unx,$(GUIBASE)),$(filter-out MACOSX,$(OS))), \
vclplug_gen \
$(if $(ENABLE_TDE),vclplug_tde) \
diff --git a/avmedia/Library_avmedia.mk b/avmedia/Library_avmedia.mk
index 6bfc7910a3b0..ec70670487ce 100644
--- a/avmedia/Library_avmedia.mk
+++ b/avmedia/Library_avmedia.mk
@@ -42,7 +42,6 @@ $(eval $(call gb_Library_use_libraries,avmedia,\
tl \
utl \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/avmedia/Library_avmediaogl.mk b/avmedia/Library_avmediaogl.mk
index 3bbebe885b97..3ff981811846 100644
--- a/avmedia/Library_avmediaogl.mk
+++ b/avmedia/Library_avmediaogl.mk
@@ -29,7 +29,6 @@ $(eval $(call gb_Library_use_libraries,avmediaogl,\
salhelper \
tl \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index aaad33500c21..d9eea58ff92f 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -688,7 +688,7 @@ namespace basegfx
B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate)
{
- if(rCandidate.count() > 1L)
+ if(rCandidate.count() > 0L)
{
solver aSolver(rCandidate);
return aSolver.getB2DPolyPolygon();
diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk
index b5d33774c518..589e6011f3c2 100644
--- a/canvas/Library_oglcanvas.mk
+++ b/canvas/Library_oglcanvas.mk
@@ -20,7 +20,6 @@ $(eval $(call gb_Library_use_libraries,oglcanvas,\
cppuhelper \
comphelper \
vcl \
- vclopengl \
tk \
tl \
i18nlangtag \
diff --git a/chart2/Library_chartcontroller.mk b/chart2/Library_chartcontroller.mk
index b147fc103829..f77ef70b9056 100644
--- a/chart2/Library_chartcontroller.mk
+++ b/chart2/Library_chartcontroller.mk
@@ -43,7 +43,6 @@ $(eval $(call gb_Library_use_libraries,chartcontroller,\
ucbhelper \
utl \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/chart2/Library_chartcore.mk b/chart2/Library_chartcore.mk
index 2543eaa557ab..34406538d72c 100644
--- a/chart2/Library_chartcore.mk
+++ b/chart2/Library_chartcore.mk
@@ -57,8 +57,6 @@ $(eval $(call gb_Library_use_libraries,chartcore,\
ucbhelper \
utl \
vcl \
- $(if $(filter FREEBSD LINUX MACOSX WNT,$(OS)), \
- vclopengl) \
$(gb_UWINAPI) \
))
diff --git a/chart2/Library_chartopengl.mk b/chart2/Library_chartopengl.mk
index bd47e89c2c38..83d52d8bfa8d 100644
--- a/chart2/Library_chartopengl.mk
+++ b/chart2/Library_chartopengl.mk
@@ -48,7 +48,6 @@ $(eval $(call gb_Library_use_libraries,chartopengl,\
ucbhelper \
utl \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/chart2/source/view/main/GL3DRenderer.cxx b/chart2/source/view/main/GL3DRenderer.cxx
index 8277d083fd35..092810a0557b 100755
--- a/chart2/source/view/main/GL3DRenderer.cxx
+++ b/chart2/source/view/main/GL3DRenderer.cxx
@@ -2493,6 +2493,9 @@ glm::mat4 OpenGL3DRenderer::GetGlobalScaleMatrix()
void OpenGL3DRenderer::RenderBatchBars(bool bNewScene)
{
+ if (m_BarSurface[0].modelMatrixList.empty())
+ return;
+
if(bNewScene)
{
GetBatchBarsInfo();
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 4017923c5464..5ca96020fb4d 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -22,9 +22,12 @@
# include "GL/glxew.h"
# include <postx.h>
#elif defined( _WIN32 )
+#ifndef INCLUDED_PRE_POST_WIN_H
+#define INCLUDED_PRE_POST_WIN_H
# include "prewin.h"
# include "postwin.h"
#endif
+#endif
#if defined( _WIN32 )
#include <GL/glext.h>
@@ -99,14 +102,16 @@ struct GLWindow
#elif defined( IOS )
#elif defined( ANDROID )
#elif defined( UNX )
- Display* dpy;
- int screen;
- Window win;
+ Display* dpy;
+ int screen;
+ Window win;
+ Pixmap pix;
#if defined( GLX_EXT_texture_from_pixmap )
GLXFBConfig fbc;
#endif
XVisualInfo* vi;
GLXContext ctx;
+ GLXPixmap glPix;
bool HasGLXExtension( const char* name ) { return checkExtension( (const GLubyte*) name, (const GLubyte*) GLXExtensions ); }
const char* GLXExtensions;
@@ -117,8 +122,6 @@ struct GLWindow
const GLubyte* GLExtensions;
bool bMultiSampleSupported;
- bool HasGLExtension( const char* name ) { return checkExtension( (const GLubyte*) name, GLExtensions ); }
-
GLWindow()
:
#if defined( _WIN32 )
@@ -134,6 +137,7 @@ struct GLWindow
#endif
vi(NULL),
ctx(0),
+ glPix(0),
GLXExtensions(NULL),
#endif
bpp(0),
@@ -154,10 +158,21 @@ public:
~OpenGLContext();
void requestLegacyContext();
+ void requestSingleBufferedRendering();
+ void requestVirtualDevice();
bool init(vcl::Window* pParent = 0);
bool init(SystemChildWindow* pChildWindow);
+// these methods are for the deep platform layer, don't use them in normal code
+// only in vcl's platform code
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+ bool init(Display* dpy, Window win, int screen);
+ bool init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen);
+#elif defined( _WIN32 )
+ bool init( HDC hDC, HWND hWnd );
+#endif
+
void makeCurrent();
void resetCurrent();
void swapBuffers();
@@ -166,7 +181,7 @@ public:
void setWinPosAndSize(const Point &rPos, const Size& rSize);
void setWinSize(const Size& rSize);
- GLWindow& getOpenGLWindow() { return m_aGLWin;}
+ const GLWindow& getOpenGLWindow() const { return m_aGLWin;}
SystemChildWindow* getChildWindow();
const SystemChildWindow* getChildWindow() const;
@@ -183,8 +198,12 @@ public:
static SystemWindowData generateWinData(vcl::Window* pParent, bool bRequestLegacyContext);
private:
+ SAL_DLLPRIVATE bool InitGLEW();
SAL_DLLPRIVATE bool initWindow();
SAL_DLLPRIVATE bool ImplInit();
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+ SAL_DLLPRIVATE void initGLWindow(Visual* pVisual);
+#endif
#if defined(MACOSX)
NSOpenGLView* getOpenGLView();
@@ -197,6 +216,11 @@ private:
boost::scoped_ptr<SystemChildWindow> m_pChildWindowGC;
bool mbInitialized;
bool mbRequestLegacyContext;
+ bool mbUseDoubleBufferedRendering;
+ bool mbRequestVirtualDevice;
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+ bool mbPixmap; // is a pixmap instead of a window
+#endif
};
#endif
diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx
index 8c04e320d4be..d49f579a5550 100644
--- a/include/vcl/opengl/OpenGLHelper.hxx
+++ b/include/vcl/opengl/OpenGLHelper.hxx
@@ -16,6 +16,12 @@
#include <rtl/ustring.hxx>
+#if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
+# include <prex.h>
+# include "GL/glxew.h"
+# include <postx.h>
+#endif
+
class VCLOPENGL_DLLPUBLIC OpenGLHelper
{
public:
@@ -46,6 +52,16 @@ public:
static float getGLVersion();
static void checkGLError(const char* aFile, size_t nLine);
+
+ /**
+ * checks if the system supports all features that are necessary for the OpenGL VCL support
+ */
+ static bool supportsVCLOpenGL();
+
+#if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
+ static bool GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rVI);
+ static GLXFBConfig GetPixmapFBConfig( Display* pDisplay, bool& bInverted );
+#endif
};
#define CHECK_GL_ERROR() OpenGLHelper::checkGLError(__FILE__, __LINE__)
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 6beb928cbe9b..80d8576a8612 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -514,6 +514,8 @@ public:
const Point& rSrcPt, const Size& rSrcSize,
sal_uInt16 nFlags = 0 );
+ virtual bool SwapBuffers();
+
protected:
virtual void CopyDeviceArea( SalTwoRect& aPosAry, sal_uInt32 nFlags);
diff --git a/officecfg/registry/data/org/openoffice/Office/Common.xcu b/officecfg/registry/data/org/openoffice/Office/Common.xcu
index 407be356e0a1..6cd4e22da7a8 100644
--- a/officecfg/registry/data/org/openoffice/Office/Common.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/Common.xcu
@@ -690,12 +690,4 @@
<value oor:external="com.sun.star.configuration.backend.GconfBackend UndoSteps"/>
</prop>
</node>
- <node oor:name="_3D_Engine" install:module="gconflockdown">
- <prop oor:name="OpenGL">
- <value oor:external="com.sun.star.configuration.backend.GconfBackend OpenGL"/>
- </prop>
- <prop oor:name="OpenGL_Faster">
- <value oor:external="com.sun.star.configuration.backend.GconfBackend OpenGL_Faster"/>
- </prop>
- </node>
</oor:component-data>
diff --git a/officecfg/registry/data/org/openoffice/Setup.xcu b/officecfg/registry/data/org/openoffice/Setup.xcu
index 51ff7c01be99..9b17125b66f1 100644
--- a/officecfg/registry/data/org/openoffice/Setup.xcu
+++ b/officecfg/registry/data/org/openoffice/Setup.xcu
@@ -912,12 +912,10 @@
<it>/org.openoffice.Office.Common/View/FontAntiAliasing</it>
<it>/org.openoffice.Office.Common/View/Localization</it>
<it>/org.openoffice.Office.Common/View/Menu</it>
- <it>/org.openoffice.Office.Common/_3D_Engine</it>
</value>
</prop>
<prop oor:name="ExcludedNodes">
<value>
- <it>/org.openoffice.Office.Common/_3D_Engine/OpenGL</it>
<it>/org.openoffice.Office.Common/Help/Registration</it>
</value>
</prop>
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index 9e72795692eb..e19df23e094c 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -847,6 +847,18 @@
</group>
</templates>
<component>
+ <group oor:name="VCL">
+ <info>
+ <desc>Contains settings for VCL.</desc>
+ </info>
+ <prop oor:name="UseOpenGL" oor:type="xs:boolean" oor:nillable="false">
+ <info>
+ <desc>Specifies if OpenGL rendering should be used in VCL backends
+ supporting it.</desc>
+ </info>
+ <value>false</value>
+ </prop>
+ </group>
<group oor:name="InternalMSExport">
<info>
<desc>Contains internal MSExport settings that are common for all
@@ -897,63 +909,6 @@
</info>
</prop>
</group>
- <group oor:name="_3D_Engine">
- <info>
- <desc>Specifies settings for the 3D engine.</desc>
- </info>
- <prop oor:name="Dithering" oor:type="xs:boolean" oor:nillable="false">
- <!-- OldPath: 3D-Engine/Dithering -->
- <!-- OldLocation: soffice.ini -->
- <!-- UIHints: Tools - Options - General - Other - [Section] 3D-View -->
- <info>
- <desc>Specifies if dithering is used to display more colors with few
- colors available.</desc>
- <label>Use Dithering</label>
- </info>
- <value>true</value>
- </prop>
- <prop oor:name="OpenGL" oor:type="xs:boolean" oor:nillable="false">
- <!-- OldPath: 3D-Engine/OpenGL -->
- <!-- OldLocation: soffice.ini -->
- <!-- UIHints: Tools - Options - General - Other - [Section] 3D-View -->
- <info>
- <desc>Specifies if 3D graphics from Draw and Impress will be displayed
- on the user's system using an OpenGL capable hardware. If the system
- does not have an OpenGL capable hardware, this setting will be
- ignored. The 3D display is always done per software.</desc>
- <label>Use OpenGL</label>
- </info>
- <value>false</value>
- </prop>
- <prop oor:name="OpenGL_Faster" oor:type="xs:boolean" oor:nillable="false">
- <!-- OldPath: 3D-Engine/OpenGL_Faster -->
- <!-- OldLocation: soffice.ini -->
- <!-- UIHints: Tools - Options - General - Other - [Section] 3D-View -->
- <info>
- <desc>Specifies whether all geometry data will be simultaneously
- transferred in an array to the graphic driver. Not every graphic
- driver correctly supports this OpenGL capability. For this reason,
- this option can be deactivated in case of presentation errors of 3D
- output. All geometry data will be then transferred as single
- components. This option is only available if OpenGL is used, otherwise
- it is disabled.</desc>
- <label>Optimized output</label>
- </info>
- <value>true</value>
- </prop>
- <prop oor:name="ShowFull" oor:type="xs:boolean" oor:nillable="false">
- <!-- OldPath: 3D-Engine/ShowFull -->
- <!-- OldLocation: soffice.ini -->
- <!-- UIHints: Tools - Options - General - Other - [Section] 3D-View -->
- <info>
- <desc>Specifies interaction with full display. If a 3-D object is
- rotated or moved, the full display is rotated or moved and not a grid
- frame.</desc>
- <label>Object refresh during interaction</label>
- </info>
- <value>false</value>
- </prop>
- </group>
<group oor:name="Dictionaries">
<info>
<desc>Contains settings related to dictionaries.</desc>
@@ -2124,16 +2079,6 @@
<desc>Contains settings which are used during the Office startup to
check for unfinished work.</desc>
</info>
- <prop oor:name="DevelopmentChart" oor:type="xs:boolean" oor:nillable="false">
- <info>
- <desc>Specifies that If this option is set to true, the new
- development chart library is used instead of the standard one. Do not
- set this option to true unless you know exactly what to do. This new
- library will be unstable and incomplete most of the time. This flag
- will be removed when the new library is in a stable state.</desc>
- </info>
- <value>false</value>
- </prop>
<set oor:name="RecoveryList" oor:node-type="RecoveryEntry">
<info>
<desc>Contains the documents that were opened when the office
diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
index 9c5606e66e55..b4397368bcb9 100644
--- a/sc/CppunitTest_sc_ucalc.mk
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -70,7 +70,6 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_ucalc, \
utl \
vbahelper \
vcl \
- vclopengl \
xo \
$(gb_UWINAPI) \
))
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 364872083a0f..042fc156e63f 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -88,7 +88,6 @@ $(eval $(call gb_Library_use_libraries,sc,\
$(call gb_Helper_optional,SCRIPTING, \
vbahelper) \
vcl \
- vclopengl \
xo \
$(gb_UWINAPI) \
))
diff --git a/sc/workben/opencl/platform_detect.cxx b/sc/workben/opencl/platform_detect.cxx
index b0a9c610d7e1..ef4558818d24 100644
--- a/sc/workben/opencl/platform_detect.cxx
+++ b/sc/workben/opencl/platform_detect.cxx
@@ -7,13 +7,17 @@
using namespace std;
+#ifdef WIN32
+#define OPENCL_DLL_NAME "OpenCL.dll"
+#elif defined(MACOSX)
+#define OPENCL_DLL_NAME NULL
+#else
+#define OPENCL_DLL_NAME "libOpenCL.so"
+#endif
+
int main()
{
- const char* dllname = "libOpenCL.so"; // on Linux
-// const char* dllname = "OpenCL.dll"; // from GPU driver.
-// const char* dllname = "amdocl.dll"; // from AMD SDK
-// const char* dllname = "intelocl.dll"; // from Intel SDK
- int status = clewInit(dllname);
+ int status = clewInit(OPENCL_DLL_NAME);
if (status < 0)
{
cout << "failed to load" << endl;
diff --git a/shell/source/backends/gconfbe/gconfaccess.cxx b/shell/source/backends/gconfbe/gconfaccess.cxx
index 371b76603043..1b30545fc840 100644
--- a/shell/source/backends/gconfbe/gconfaccess.cxx
+++ b/shell/source/backends/gconfbe/gconfaccess.cxx
@@ -700,22 +700,6 @@ ConfigurationValue const ConfigurationValues[] =
},
{
- SETTING_ENABLE_OPENGL,
- "/apps/openoffice/use_opengl",
- RTL_CONSTASCII_STRINGPARAM("OpenGL"),
- false,
- SETTINGS_LAST
- },
-
- {
- SETTING_OPTIMIZE_OPENGL,
- "/apps/openoffice/optimize_opengl",
- RTL_CONSTASCII_STRINGPARAM("OpenGL_Faster"),
- false,
- SETTINGS_LAST
- },
-
- {
SETTING_USE_SYSTEM_FONT,
"/apps/openoffice/use_system_font",
RTL_CONSTASCII_STRINGPARAM("AccessibilityIsSystemFont"),
diff --git a/shell/source/backends/gconfbe/gconfaccess.hxx b/shell/source/backends/gconfbe/gconfaccess.hxx
index 699c4869e29b..bad128df9b67 100644
--- a/shell/source/backends/gconfbe/gconfaccess.hxx
+++ b/shell/source/backends/gconfbe/gconfaccess.hxx
@@ -62,8 +62,6 @@ enum ConfigurationSetting
SETTING_SHOW_INACTIVE_MENUITEMS,
SETTING_SHOW_FONT_PREVIEW,
SETTING_SHOW_FONT_HISTORY,
- SETTING_ENABLE_OPENGL,
- SETTING_OPTIMIZE_OPENGL,
SETTING_SAVE_DOCUMENT_WINDOWS,
SETTING_SAVE_DOCUMENT_VIEW_INFO,
SETTING_USE_SYSTEM_FONT,
diff --git a/slideshow/Library_OGLTrans.mk b/slideshow/Library_OGLTrans.mk
index 6a9d2ac1fa62..809ca1486573 100644
--- a/slideshow/Library_OGLTrans.mk
+++ b/slideshow/Library_OGLTrans.mk
@@ -31,7 +31,6 @@ $(eval $(call gb_Library_use_libraries,OGLTrans,\
cppuhelper \
sal \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/slideshow/Library_slideshow.mk b/slideshow/Library_slideshow.mk
index d5af9a160c2a..5d01391ce55b 100644
--- a/slideshow/Library_slideshow.mk
+++ b/slideshow/Library_slideshow.mk
@@ -48,7 +48,6 @@ $(eval $(call gb_Library_use_libraries,slideshow,\
tl \
utl \
vcl \
- vclopengl \
$(gb_UWINAPI) \
))
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
index 2d5d062a568e..22fca9170247 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
@@ -446,7 +446,7 @@ void OGLTransitionerImpl::impl_prepareSlides()
#if defined( GLX_EXT_texture_from_pixmap )
- GLWindow& rGLWindow(mpContext->getOpenGLWindow());
+ const GLWindow& rGLWindow(mpContext->getOpenGLWindow());
if( GLXEW_EXT_texture_from_pixmap && xLeavingSet.is() && xEnteringSet.is() && mbHasTFPVisual ) {
Sequence< Any > leaveArgs;
@@ -1218,7 +1218,7 @@ void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeExc
if(mpTransition)
{
- GLWindow& rGLWindow(mpContext->getOpenGLWindow());
+ const GLWindow& rGLWindow(mpContext->getOpenGLWindow());
mpTransition->display( nTime, maLeavingSlideGL, maEnteringSlideGL,
maSlideSize.Width, maSlideSize.Height,
static_cast<double>(rGLWindow.Width),
@@ -1261,7 +1261,7 @@ void OGLTransitionerImpl::disposeTextures()
mpContext->makeCurrent();
#if defined( GLX_EXT_texture_from_pixmap )
- GLWindow& rGLWindow(mpContext->getOpenGLWindow());
+ const GLWindow& rGLWindow(mpContext->getOpenGLWindow());
if( mbUseLeavingPixmap ) {
glXReleaseTexImageEXT( rGLWindow.dpy, maLeavingPixmapGL, GLX_FRONT_LEFT_EXT );
diff --git a/solenv/gbuild/extensions/pre_MergedLibsList.mk b/solenv/gbuild/extensions/pre_MergedLibsList.mk
index 8f8320a2336e..3c73485ccaf5 100644
--- a/solenv/gbuild/extensions/pre_MergedLibsList.mk
+++ b/solenv/gbuild/extensions/pre_MergedLibsList.mk
@@ -153,7 +153,6 @@ gb_MERGEDLIBS := \
utl \
uui \
vcl \
- vclopengl \
$(if $(and $(filter unx,$(GUIBASE)),$(filter-out MACOSX,$(OS))), \
$(if $(ENABLE_HEADLESS),,vclplug_svp) \
) \
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 1536ee6ae551..23cb969a978a 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -77,7 +77,6 @@ $(eval $(call gb_Library_use_libraries,svxcore,\
ucbhelper \
utl \
vcl \
- vclopengl \
xo \
$(gb_UWINAPI) \
))
diff --git a/vcl/Executable_icontest.mk b/vcl/Executable_icontest.mk
index dd5ee952a90c..d7962d846523 100644
--- a/vcl/Executable_icontest.mk
+++ b/vcl/Executable_icontest.mk
@@ -53,7 +53,6 @@ $(eval $(call gb_Executable_use_libraries,icontest,\
tl \
ucbhelper \
vcl \
- vclopengl \
))
$(eval $(call gb_Executable_add_exception_objects,icontest,\
diff --git a/vcl/Executable_outdevgrind.mk b/vcl/Executable_outdevgrind.mk
new file mode 100644
index 000000000000..f1a822f5f4a7
--- /dev/null
+++ b/vcl/Executable_outdevgrind.mk
@@ -0,0 +1,39 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# 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/.
+#
+
+$(eval $(call gb_Executable_Executable,outdevgrind))
+
+$(eval $(call gb_Executable_use_api,outdevgrind,\
+ offapi \
+ udkapi \
+))
+
+$(eval $(call gb_Executable_use_external,outdevgrind,boost_headers))
+
+$(eval $(call gb_Executable_set_include,outdevgrind,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/vcl/inc \
+ -I$(SRCDIR)/solenv/inc \
+))
+
+$(eval $(call gb_Executable_use_libraries,outdevgrind,\
+ tl \
+ sal \
+ vcl \
+ cppu \
+ cppuhelper \
+ comphelper \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,outdevgrind,\
+ vcl/workben/outdevgrind \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Executable_vcldemo.mk b/vcl/Executable_vcldemo.mk
index fb29b9a1991f..561f7d6d564e 100644
--- a/vcl/Executable_vcldemo.mk
+++ b/vcl/Executable_vcldemo.mk
@@ -36,4 +36,8 @@ $(eval $(call gb_Executable_add_exception_objects,vcldemo,\
vcl/workben/vcldemo \
))
+$(eval $(call gb_Executable_use_static_libraries,vcldemo,\
+ vclmain \
+))
+
# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index dea1d8d6c74e..81f774a98644 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -45,6 +45,7 @@ $(eval $(call gb_Library_set_include,vcl,\
$(eval $(call gb_Library_add_defs,vcl,\
-DVCL_DLLIMPLEMENTATION \
+ -DVCLOPENGL_DLLIMPLEMENTATION \
-DCUI_DLL_NAME=\"$(call gb_Library_get_runtime_filename,$(call gb_Library__get_name,cui))\" \
-DDESKTOP_DETECTOR_DLL_NAME=\"$(call gb_Library_get_runtime_filename,$(call gb_Library__get_name,desktop_detector))\" \
-DTK_DLL_NAME=\"$(call gb_Library_get_runtime_filename,$(call gb_Library__get_name,tk))\" \
@@ -89,6 +90,17 @@ $(eval $(call gb_Library_add_libs,vcl,\
-lobjc \
))
endif
+ifeq ($(OS),MACOSX)
+
+$(eval $(call gb_Library_add_cxxflags,vcl,\
+ $(gb_OBJCXXFLAGS) \
+))
+
+$(eval $(call gb_Library_add_exception_objects,vcl,\
+ vcl/osx/OpenGLWrapper \
+))
+
+endif
ifeq ($(ENABLE_JAVA),TRUE)
$(eval $(call gb_Library_use_libraries,vcl,\
@@ -99,13 +111,24 @@ endif
$(eval $(call gb_Library_use_externals,vcl,\
boost_headers \
gio \
+ glew \
+ glm_headers \
harfbuzz \
- icuuc \
icu_headers \
+ icuuc \
lcms2 \
+ mdds_headers \
+ mesa_headers \
))
$(eval $(call gb_Library_add_exception_objects,vcl,\
+ vcl/opengl/gdiimpl \
+ vcl/opengl/salbmp \
+ vcl/opengl/scale \
+ vcl/opengl/texture \
+ vcl/source/opengl/OpenGLContext \
+ vcl/source/opengl/OpenGLHelper \
+ vcl/source/window/openglwin \
vcl/source/window/settings \
vcl/source/window/paint \
vcl/source/window/resource \
@@ -273,6 +296,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/region \
vcl/source/gdi/regionband \
vcl/source/gdi/salgdilayout \
+ vcl/source/gdi/salgdiimpl \
vcl/source/gdi/sallayout \
vcl/source/gdi/salmisc \
vcl/source/gdi/salnativewidgets-none \
@@ -475,6 +499,7 @@ $(eval $(call gb_Library_use_system_darwin_frameworks,vcl,\
Cocoa \
Carbon \
CoreFoundation \
+ OpenGL \
))
ifneq ($(ENABLE_MACOSX_SANDBOX),TRUE)
@@ -532,6 +557,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/unx/generic/plugadapt/salplug \
vcl/unx/generic/printer/jobdata \
vcl/unx/generic/printer/ppdparser \
+ vcl/unx/generic/gdi/x11windowprovider \
$(if $(filter TRUE,$(ENABLE_CUPS)),\
vcl/unx/generic/printer/cupsmgr \
vcl/unx/generic/printer/printerinfomanager \
@@ -618,11 +644,13 @@ endif
ifeq ($(OS),WNT)
$(eval $(call gb_Library_add_exception_objects,vcl,\
+ vcl/opengl/win/gdiimpl \
vcl/win/source/app/saldata \
vcl/win/source/app/salinfo \
vcl/win/source/app/salinst \
vcl/win/source/app/salshl \
vcl/win/source/app/saltimer \
+ vcl/win/source/gdi/gdiimpl \
vcl/win/source/gdi/salbmp \
vcl/win/source/gdi/salgdi \
vcl/win/source/gdi/salgdi2 \
@@ -643,9 +671,11 @@ $(eval $(call gb_Library_use_system_win32_libs,vcl,\
advapi32 \
gdi32 \
gdiplus \
+ glu32 \
imm32 \
mpr \
msimg32 \
+ opengl32 \
ole32 \
shell32 \
usp10 \
@@ -671,6 +701,9 @@ $(eval $(call gb_Library_add_libs,vcl,\
-lm \
-ldl \
-lpthread \
+ -lGL \
+ -lGLU \
+ -lX11 \
))
endif
diff --git a/vcl/Library_vclopengl.mk b/vcl/Library_vclopengl.mk
deleted file mode 100644
index e61dd8a9bb31..000000000000
--- a/vcl/Library_vclopengl.mk
+++ /dev/null
@@ -1,88 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_Library_Library,vclopengl))
-
-$(eval $(call gb_Library_set_include,vclopengl,\
- -I$(SRCDIR)/vcl/inc/ \
- $$(INCLUDE) \
-))
-
-$(eval $(call gb_Library_add_defs,vclopengl,\
- -DVCLOPENGL_DLLIMPLEMENTATION \
-))
-
-$(eval $(call gb_Library_use_externals,vclopengl,\
- boost_headers \
- mdds_headers \
- glm_headers \
- mesa_headers \
- glew \
-))
-
-$(eval $(call gb_Library_use_sdk_api,vclopengl))
-
-$(eval $(call gb_Library_use_libraries,vclopengl,\
- comphelper \
- cppu \
- cppuhelper \
- sal \
- tl \
- vcl \
- $(gb_UWINAPI) \
-))
-
-$(eval $(call gb_Library_add_exception_objects,vclopengl,\
- vcl/source/opengl/OpenGLContext \
- vcl/source/opengl/OpenGLHelper \
- vcl/source/window/openglwin \
-))
-
-ifeq ($(OS),MACOSX)
-
-$(eval $(call gb_Library_add_cxxflags,vclopengl,\
- $(gb_OBJCXXFLAGS) \
-))
-
-$(eval $(call gb_Library_add_libs,vcl,\
- -framework IOKit \
- -F/System/Library/PrivateFrameworks \
- -framework CoreUI \
- -lobjc \
-))
-
-$(eval $(call gb_Library_add_exception_objects,vclopengl,\
- vcl/osx/OpenGLWrapper \
-))
-
-endif
-
-ifeq ($(strip $(OS)),WNT)
-$(eval $(call gb_Library_use_system_win32_libs,vclopengl,\
- opengl32 \
- gdi32 \
- glu32 \
-))
-else ifeq ($(OS),MACOSX)
-$(eval $(call gb_Library_use_system_darwin_frameworks,vclopengl,\
- OpenGL \
- Cocoa \
- Carbon \
- CoreFoundation \
-))
-else ifeq ($(OS),LINUX)
-$(eval $(call gb_Library_add_libs,vclopengl,\
- -ldl \
- -lGL \
- -lGLU \
- -lX11 \
-))
-endif
-
-# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index c3f00aa4eef2..73e5d010e597 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -24,6 +24,10 @@ $(eval $(call gb_Library_set_include,vclplug_gen,\
-I$(SRCDIR)/vcl/inc \
))
+$(eval $(call gb_Library_use_custom_headers,vclplug_gen,\
+ officecfg/registry \
+))
+
$(eval $(call gb_Library_use_sdk_api,vclplug_gen))
$(eval $(call gb_Library_use_libraries,vclplug_gen,\
@@ -47,6 +51,7 @@ $(eval $(call gb_Library_use_externals,vclplug_gen,\
boost_headers \
cairo \
graphite \
+ glew \
harfbuzz \
icuuc \
valgrind \
@@ -58,6 +63,8 @@ $(eval $(call gb_Library_add_libs,vclplug_gen,\
-lXext \
-lSM \
-lICE \
+ -lGL \
+ -lGLU \
))
$(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
@@ -83,7 +90,12 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/generic/dtrans/X11_selection \
vcl/unx/generic/dtrans/X11_service \
vcl/unx/generic/dtrans/X11_transferable \
+ vcl/unx/generic/gdi/cairotextrender \
+ vcl/unx/generic/gdi/x11cairotextrender \
vcl/unx/generic/gdi/gcach_xpeer \
+ vcl/unx/generic/gdi/gdiimpl \
+ vcl/unx/generic/gdi/pixmap \
+ vcl/unx/generic/gdi/openglx11cairotextrender \
vcl/unx/generic/gdi/salbmp \
vcl/unx/generic/gdi/salgdi2 \
vcl/unx/generic/gdi/salgdi3 \
@@ -95,6 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/generic/window/salobj \
vcl/unx/x11/x11sys \
vcl/unx/x11/xlimits \
+ vcl/opengl/x11/gdiimpl \
))
# ultimately we want to split the x11 dependencies out
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 51c5d3ff0ab1..5d1d2d2ad7fc 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -22,17 +22,18 @@ $(eval $(call gb_Module_Module,vcl))
$(eval $(call gb_Module_add_targets,vcl,\
CustomTarget_afm_hash \
Library_vcl \
+ Package_opengl \
$(if $(filter DESKTOP,$(BUILD_TYPE)), \
StaticLibrary_vclmain \
Executable_ui-previewer \
$(if $(filter LINUX MACOSX WNT,$(OS)), \
- Executable_icontest)) \
+ Executable_icontest \
+ Executable_outdevgrind \
+ Executable_vcldemo )) \
$(if $(filter-out ANDROID IOS WNT,$(OS)), \
Executable_svdemo \
Executable_svptest \
- Executable_svpclient \
- Executable_vcldemo) \
- Library_vclopengl \
+ Executable_svpclient) \
))
$(eval $(call gb_Module_add_l10n_targets,vcl,\
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
new file mode 100644
index 000000000000..79dabb70bbb6
--- /dev/null
+++ b/vcl/Package_opengl.mk
@@ -0,0 +1,24 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
+
+$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
+ convolutionFragmentShader.glsl \
+ maskFragmentShader.glsl \
+ maskVertexShader.glsl \
+ maskedTextureFragmentShader.glsl \
+ maskedTextureVertexShader.glsl \
+ solidFragmentShader.glsl \
+ solidVertexShader.glsl \
+ textureFragmentShader.glsl \
+ textureVertexShader.glsl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx
index 3920aea25f2d..b5fcc241d75d 100644
--- a/vcl/headless/svpbmp.cxx
+++ b/vcl/headless/svpbmp.cxx
@@ -339,6 +339,11 @@ bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
return false;
}
+bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, sal_uInt32 /*nScaleFlag*/ )
+{
+ return false;
+}
+
sal_uInt32 SvpSalBitmap::getBitCountFromScanlineFormat( basebmp::Format nFormat )
{
sal_uInt32 nBitCount = 1;
diff --git a/vcl/inc/cairotextrender.hxx b/vcl/inc/cairotextrender.hxx
new file mode 100644
index 000000000000..e5db2ab7e612
--- /dev/null
+++ b/vcl/inc/cairotextrender.hxx
@@ -0,0 +1,129 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_CAIROTEXTRENDER_HXX
+#define INCLUDED_VCL_INC_UNX_CAIROTEXTRENDER_HXX
+
+#include "textrender.hxx"
+#include <vcl/region.hxx>
+#include <deque>
+
+typedef struct FT_FaceRec_* FT_Face;
+
+class PspSalPrinter;
+class PspSalInfoPrinter;
+class ServerFont;
+class GlyphCache;
+class ImplLayoutArgs;
+class ServerFontLayout;
+class PhysicalFontCollection;
+class PhysicalFontFace;
+struct _cairo_surface_t;
+typedef struct _cairo_surface cairo_surface_t;
+typedef struct _cairo cairo_t;
+
+class CairoFontsCache
+{
+public:
+ struct CacheId
+ {
+ FT_Face maFace;
+ const void *mpOptions;
+ bool mbEmbolden;
+ bool mbVerticalMetrics;
+ bool operator ==(const CacheId& rOther) const
+ {
+ return maFace == rOther.maFace &&
+ mpOptions == rOther.mpOptions &&
+ mbEmbolden == rOther.mbEmbolden &&
+ mbVerticalMetrics == rOther.mbVerticalMetrics;
+ }
+ };
+private:
+ static int mnRefCount;
+ typedef std::deque< std::pair<void *, CacheId> > LRUFonts;
+ static LRUFonts maLRUFonts;
+public:
+ CairoFontsCache();
+ static void CacheFont(void *pFont, const CacheId &rId);
+ static void* FindCachedFont(const CacheId &rId);
+ ~CairoFontsCache();
+};
+
+class CairoTextRender : public TextRenderImpl
+{
+ bool mbPrinter;
+ ServerFont* mpServerFont[ MAX_FALLBACK ];
+
+ SalColor nTextColor_;
+ CairoFontsCache m_aCairoFontsCache;
+
+protected:
+ virtual GlyphCache& getPlatformGlyphCache() = 0;
+ virtual cairo_surface_t* getCairoSurface() = 0;
+ virtual void drawSurface(cairo_t* cr) = 0;
+
+bool setFont( const FontSelectPattern *pEntry, int nFallbackLevel );
+
+ virtual void clipRegion(cairo_t* cr) = 0;
+
+public:
+ CairoTextRender(bool bPrinter);
+
+
+ virtual void SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
+ virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
+ virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
+ virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
+ virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
+ virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
+ virtual void ClearDevFontCache() SAL_OVERRIDE;
+ virtual bool AddTempDevFont( PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) SAL_OVERRIDE;
+ virtual bool CreateFontSubset( const OUString& rToFile,
+ const PhysicalFontFace*,
+ sal_GlyphId* pGlyphIDs,
+ sal_uInt8* pEncoding,
+ sal_Int32* pWidths,
+ int nGlyphs,
+ FontSubsetInfo& rInfo
+ ) SAL_OVERRIDE;
+ virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded ) SAL_OVERRIDE;
+ virtual const void* GetEmbedFontData( const PhysicalFontFace*,
+ const sal_Ucs* pUnicodes,
+ sal_Int32* pWidths,
+ FontSubsetInfo& rInfo,
+ long* pDataLen ) SAL_OVERRIDE;
+ virtual void FreeEmbedFontData( const void* pData, long nDataLen ) SAL_OVERRIDE;
+ virtual void GetGlyphWidths( const PhysicalFontFace*,
+ bool bVertical,
+ Int32Vector& rWidths,
+ Ucs2UIntMap& rUnicodeEnc ) SAL_OVERRIDE;
+ virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) SAL_OVERRIDE;
+ virtual bool GetGlyphOutline( sal_GlyphId nIndex, ::basegfx::B2DPolyPolygon& ) SAL_OVERRIDE;
+ virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) SAL_OVERRIDE;
+ virtual void DrawServerFontLayout( const ServerFontLayout& ) SAL_OVERRIDE;
+ virtual SystemFontData GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE;
+
+private:
+ bool bDisableGraphite_;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/generic/genpspgraphics.h b/vcl/inc/generic/genpspgraphics.h
index 30c8fecd5eea..fb7169afa804 100644
--- a/vcl/inc/generic/genpspgraphics.h
+++ b/vcl/inc/generic/genpspgraphics.h
@@ -192,6 +192,8 @@ public:
virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE;
virtual SystemFontData GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE;
+
+ virtual bool SwapBuffers() SAL_OVERRIDE { return false; };
};
#endif // INCLUDED_VCL_INC_GENERIC_GENPSPGRAPHICS_H
diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx
index ba44ae8412b3..ddfc7a8ef965 100644
--- a/vcl/inc/generic/glyphcache.hxx
+++ b/vcl/inc/generic/glyphcache.hxx
@@ -205,6 +205,7 @@ private:
friend class ServerFontLayout;
friend class ImplServerFontEntry;
friend class X11SalGraphics;
+ friend class CairoTextRender;
void AddRef() const { ++mnRefCount; }
long GetRefCount() const { return mnRefCount; }
diff --git a/vcl/inc/graphite_serverfont.hxx b/vcl/inc/graphite_serverfont.hxx
index 0d533e00b7c2..7dfde21551bc 100644
--- a/vcl/inc/graphite_serverfont.hxx
+++ b/vcl/inc/graphite_serverfont.hxx
@@ -26,6 +26,8 @@
#ifndef _MSC_VER
#include <graphite_layout.hxx>
+#include "generic/glyphcache.hxx"
+
class PhysicalFontFace;
// Modules
diff --git a/vcl/inc/headless/svpbmp.hxx b/vcl/inc/headless/svpbmp.hxx
index aecf79c29ef7..3a0da2e9f100 100644
--- a/vcl/inc/headless/svpbmp.hxx
+++ b/vcl/inc/headless/svpbmp.hxx
@@ -58,6 +58,8 @@ public:
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE;
virtual bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+ virtual bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) SAL_OVERRIDE;
+
static sal_uInt32 getBitCountFromScanlineFormat( basebmp::Format nFormat );
};
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index cbbac7a4b1dd..cd5622f9aa20 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -243,6 +243,8 @@ public:
virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE;
virtual SystemFontData GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE;
+ virtual bool SwapBuffers() SAL_OVERRIDE { return false; };
+
#ifdef IOS
void SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContext, int = 0 );
diff --git a/vcl/inc/impbmp.hxx b/vcl/inc/impbmp.hxx
index c0eb805090f8..bbe80649b23b 100644
--- a/vcl/inc/impbmp.hxx
+++ b/vcl/inc/impbmp.hxx
@@ -38,6 +38,13 @@ private:
public:
ImpBitmap();
+ /**
+ * takes ownership
+ * same as Sequence:
+ * pBmp = new ImpBitmap;
+ * pBmp->ImplSetSalBitmap(pBitmap);
+ */
+ ImpBitmap(SalBitmap* pBitmap);
~ImpBitmap();
void ImplSetSalBitmap( SalBitmap* pSalBitmap );
@@ -60,6 +67,9 @@ public:
inline void ImplSetChecksum( sal_uLong nChecksum ) { mnChecksum = nChecksum; }
inline sal_uLong ImplGetChecksum() const { return mnChecksum; }
+
+
+ bool ImplScale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag );
};
#endif // INCLUDED_VCL_INC_IMPBMP_HXX
diff --git a/vcl/inc/opengl/bmpop.hxx b/vcl/inc/opengl/bmpop.hxx
new file mode 100644
index 000000000000..d19410b2f253
--- /dev/null
+++ b/vcl/inc/opengl/bmpop.hxx
@@ -0,0 +1,35 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_BMPOP_H
+#define INCLUDED_VCL_INC_OPENGL_BMPOP_H
+
+class OpenGLSalBitmapOp
+{
+public:
+ OpenGLSalBitmapOp() {};
+ virtual ~OpenGLSalBitmapOp() {};
+
+ virtual bool Execute() = 0;
+ virtual void GetSize( Size& rSize ) const = 0;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_BMPOP_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
new file mode 100644
index 000000000000..6f7a03af09d4
--- /dev/null
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -0,0 +1,120 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_SALBMP_H
+#define INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+#include <basebmp/bitmapdevice.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
+
+#include "vcl/salbtype.hxx"
+#include "opengl/bmpop.hxx"
+#include "opengl/texture.hxx"
+
+#include <salbmp.hxx>
+
+#include <deque>
+
+// - SalBitmap -
+
+struct BitmapBuffer;
+class BitmapPalette;
+
+class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
+{
+private:
+ OpenGLContext* mpContext;
+ OpenGLTextureSharedPtr mpTexture;
+ bool mbDirtyTexture;
+ BitmapPalette maPalette;
+ basebmp::RawMemorySharedArray maUserBuffer;
+ sal_uInt16 mnBits;
+ sal_uInt16 mnBytesPerRow;
+ int mnWidth;
+ int mnHeight;
+ int mnBufWidth;
+ int mnBufHeight;
+ std::deque< OpenGLSalBitmapOp* > maPendingOps;
+
+public:
+ OpenGLSalBitmap();
+ virtual ~OpenGLSalBitmap();
+
+public:
+
+ // SalBitmap methods
+ bool Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics ) SAL_OVERRIDE;
+ bool Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount ) SAL_OVERRIDE;
+ virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
+ Size& rSize,
+ bool bMask = false ) SAL_OVERRIDE;
+
+ void Destroy() SAL_OVERRIDE;
+
+ Size GetSize() const SAL_OVERRIDE;
+ sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+ BitmapBuffer *AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE;
+ void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE;
+
+ bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+
+ bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) SAL_OVERRIDE;
+
+public:
+
+ bool Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight );
+ bool Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry );
+ GLuint GetTexture( OpenGLContext& rContext ) const;
+
+private:
+
+ GLuint CreateTexture();
+ void DeleteTexture();
+ void DrawTexture( GLuint nTexture, const SalTwoRect& rPosAry );
+ bool AllocateUserData();
+ bool ReadTexture();
+
+private:
+
+ GLuint ImplGetTextureProgram();
+ GLuint mnTexProgram;
+ GLuint mnTexSamplerUniform;
+
+ GLuint ImplGetConvolutionProgram();
+ GLuint mnConvProgram;
+ GLuint mnConvSamplerUniform;
+ GLuint mnConvKernelUniform;
+ GLuint mnConvKernelSizeUniform;
+ GLuint mnConvOffsetsUniform;
+
+ bool ImplScaleFilter( 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 );
+
+public:
+
+ bool ImplScale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag );
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_SALBMP_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
new file mode 100644
index 000000000000..f9d3ad864291
--- /dev/null
+++ b/vcl/inc/opengl/texture.hxx
@@ -0,0 +1,54 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_TEXTURE_H
+#define INCLUDED_VCL_INC_OPENGL_TEXTURE_H
+
+#include <boost/shared_ptr.hpp>
+#include <GL/glew.h>
+
+class OpenGLTexture
+{
+private:
+ GLuint mnTexture;
+ int mnWidth;
+ int mnHeight;
+ GLenum mnFilter;
+
+public:
+ OpenGLTexture();
+ OpenGLTexture( int nWidth, int nHeight );
+ OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData );
+ OpenGLTexture( int nX, int nY, int nWidth, int nHeight );
+ virtual ~OpenGLTexture();
+
+ GLuint Id() const;
+ void Bind();
+ void Unbind();
+ bool Draw();
+
+ GLenum GetFilter() const;
+ void SetFilter( GLenum nFilter );
+};
+
+typedef boost::shared_ptr< OpenGLTexture > OpenGLTextureSharedPtr;
+
+#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
new file mode 100644
index 000000000000..aa29dd9bb75c
--- /dev/null
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -0,0 +1,36 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_WIN_GDIIMPL_HXX
+#define INCLUDED_VCL_INC_OPENGL_WIN_GDIIMPL_HXX
+
+#include <vcl/dllapi.h>
+
+#include "openglgdiimpl.hxx"
+#include "win/salgdi.h"
+
+class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl
+{
+private:
+ WinSalGraphics& mrParent;
+
+public:
+ WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics);
+
+protected:
+ virtual GLfloat GetWidth() const SAL_OVERRIDE;
+ virtual GLfloat GetHeight() const SAL_OVERRIDE;
+
+public:
+
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
new file mode 100644
index 000000000000..878c7c2f054e
--- /dev/null
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+#define INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+
+#include <vcl/dllapi.h>
+
+#include "unx/salgdi.h"
+#include "unx/x11/x11gdiimpl.h"
+#include "openglgdiimpl.hxx"
+
+class VCL_PLUGIN_PUBLIC X11OpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public X11GraphicsImpl
+{
+private:
+ X11SalGraphics& mrParent;
+
+public:
+ X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent );
+ virtual ~X11OpenGLSalGraphicsImpl();
+
+protected:
+ GLfloat GetWidth() const SAL_OVERRIDE;
+ GLfloat GetHeight() const SAL_OVERRIDE;
+
+public:
+ // implementation of X11GraphicsImpl
+
+ void Init() SAL_OVERRIDE;
+ X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE;
+ bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
new file mode 100644
index 000000000000..34c26070943d
--- /dev/null
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -0,0 +1,259 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_OPENGLGDIIMPL_HXX
+#define INCLUDED_VCL_OPENGLGDIIMPL_HXX
+
+#include "salgdiimpl.hxx"
+#include <vcl/dllapi.h>
+
+#include <vcl/opengl/OpenGLContext.hxx>
+
+class SalFrame;
+class SalVirtualDevice;
+
+class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
+{
+protected:
+
+ OpenGLContext maContext;
+ SalFrame* mpFrame;
+ SalVirtualDevice* mpVDev;
+
+ SalColor mnLineColor;
+ SalColor mnFillColor;
+
+ std::vector< GLuint > maShaders;
+
+ GLuint mnSolidProgram;
+ GLuint mnColorUniform;
+
+ GLuint mnTextureProgram;
+ GLuint mnSamplerUniform;
+
+ GLuint mnMaskedTextureProgram;
+ GLuint mnMaskedSamplerUniform;
+ GLuint mnMaskSamplerUniform;
+
+ GLuint mnMaskProgram;
+ GLuint mnMaskUniform;
+ GLuint mnMaskColorUniform;
+
+ bool CreateSolidProgram( void );
+ bool CreateTextureProgram( void );
+ bool CreateMaskedTextureProgram( void );
+ bool CreateMaskProgram( void );
+
+ void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
+ void BeginSolid( SalColor nColor, double fTransparency );
+ void BeginSolid( SalColor nColor );
+ void EndSolid( void );
+ void BeginInvert( void );
+ void EndInvert( void );
+
+ void DrawPoint( long nX, long nY );
+ void DrawLine( long nX1, long nY1, long nX2, long nY2 );
+ void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+ void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
+ void DrawRect( long nX, long nY, long nWidth, long nHeight );
+ void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
+ void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
+ void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry );
+ void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry );
+ void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& rPosAry );
+ void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry );
+
+protected:
+ // get the width of the device
+ virtual GLfloat GetWidth() const = 0;
+
+ // get the height of the device
+ virtual GLfloat GetHeight() const = 0;
+
+
+public:
+ virtual ~OpenGLSalGraphicsImpl ();
+
+ OpenGLContext& GetOpenGLContext() { return maContext; }
+
+ virtual void freeResources() SAL_OVERRIDE;
+
+ virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
+ //
+ // get the depth of the device
+ virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+ // get the width of the device
+ virtual long GetGraphicsWidth() const SAL_OVERRIDE;
+
+ // set the clip region to empty
+ virtual void ResetClipRegion() SAL_OVERRIDE;
+
+ // set the line color to transparent (= don't draw lines)
+
+ virtual void SetLineColor() SAL_OVERRIDE;
+
+ // set the line color to a specific color
+ virtual void SetLineColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // set the fill color to transparent (= don't fill)
+ virtual void SetFillColor() SAL_OVERRIDE;
+
+ // set the fill color to a specific color, shapes will be
+ // filled accordingly
+ virtual void SetFillColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // enable/disable XOR drawing
+ virtual void SetXORMode( bool bSet, bool bInvertOnly ) SAL_OVERRIDE;
+
+ // set line color for raster operations
+ virtual void SetROPLineColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // set fill color for raster operations
+ virtual void SetROPFillColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // draw --> LineColor and FillColor and RasterOp and ClipRegion
+ virtual void drawPixel( long nX, long nY ) SAL_OVERRIDE;
+ virtual void drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
+
+ virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
+
+ virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) SAL_OVERRIDE;
+ virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) SAL_OVERRIDE;
+
+ virtual bool drawPolyLine(
+ const ::basegfx::B2DPolygon&,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin,
+ com::sun::star::drawing::LineCap) SAL_OVERRIDE;
+
+ virtual bool drawPolyLineBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolygonBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolyPolygonBezier(
+ sal_uInt32 nPoly,
+ const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry,
+ const sal_uInt8* const* pFlgAry ) SAL_OVERRIDE;
+
+ // CopyArea --> No RasterOp, but ClipRegion
+ virtual void copyArea(
+ long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 nFlags ) SAL_OVERRIDE;
+
+ // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+ // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+ virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
+
+ virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap ) SAL_OVERRIDE;
+
+ virtual void drawMask(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor ) SAL_OVERRIDE;
+
+ virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual SalColor getPixel( long nX, long nY ) SAL_OVERRIDE;
+
+ // invert --> ClipRegion (only Windows or VirDevs)
+ virtual void invert(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags) SAL_OVERRIDE;
+
+ virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) SAL_OVERRIDE;
+
+ virtual bool drawEPS(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ void* pPtr,
+ sal_uLong nSize ) SAL_OVERRIDE;
+
+ /** Render bitmap with alpha channel
+
+ @param rSourceBitmap
+ Source bitmap to blit
+
+ @param rAlphaBitmap
+ Alpha channel to use for blitting
+
+ @return true, if the operation succeeded, and false
+ otherwise. In this case, clients should try to emulate alpha
+ compositing themselves
+ */
+ virtual bool drawAlphaBitmap(
+ const SalTwoRect&,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
+ /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+ virtual bool drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap) SAL_OVERRIDE;
+
+ /** Render solid rectangle with given transparency
+
+ @param nTransparency
+ Transparency value (0-255) to use. 0 blits and opaque, 255 a
+ fully transparent rectangle
+ */
+ virtual bool drawAlphaRect(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency ) SAL_OVERRIDE;
+
+ virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE;
+
+ virtual bool swapBuffers() SAL_OVERRIDE;
+private:
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/quartz/salbmp.h b/vcl/inc/quartz/salbmp.h
index cd944319f818..0bde5adba211 100644
--- a/vcl/inc/quartz/salbmp.h
+++ b/vcl/inc/quartz/salbmp.h
@@ -79,6 +79,8 @@ public:
bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+ bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) SAL_OVERRIDE;
+
private:
// quartz helper
bool CreateContext();
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index eb21e09a6710..caab5774accd 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -394,6 +394,8 @@ public:
GetGraphicsData() const SAL_OVERRIDE;
virtual SystemFontData GetSysFontData( int /* nFallbacklevel */ ) const SAL_OVERRIDE;
+ virtual bool SwapBuffers() SAL_OVERRIDE { return false; };
+
private:
// differences between VCL, Quartz and kHiThemeOrientation coordinate systems
// make some graphics seem to be vertically-mirrored from a VCL perspective
diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index d279715c0dd0..227cc3f6f57b 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -54,6 +54,8 @@ public:
virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ) = 0;
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) = 0;
virtual bool GetSystemData( BitmapSystemData& rData ) = 0;
+
+ virtual bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) = 0;
};
#endif
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 2266d87ee64e..a3917bb3e78d 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -412,6 +412,8 @@ public:
sal_uInt8 nTransparency,
const OutputDevice *pOutDev );
+ virtual bool SwapBuffers() = 0;
+
virtual SystemGraphicsData GetGraphicsData() const = 0;
virtual SystemFontData GetSysFontData( int nFallbacklevel ) const = 0;
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
new file mode 100644
index 000000000000..5d4995201274
--- /dev/null
+++ b/vcl/inc/salgdiimpl.hxx
@@ -0,0 +1,210 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_SALGDIIMPL_HXX
+#define INCLUDED_VCL_INC_SALGDIIMPL_HXX
+
+#include <vcl/dllapi.h>
+
+#include <rtl/ustring.hxx>
+
+#include <tools/solar.h>
+
+#include <vcl/salgtype.hxx>
+#include <vcl/region.hxx>
+#include <vcl/salnativewidgets.hxx>
+
+#include <com/sun/star/drawing/LineCap.hpp>
+
+class SalGraphics;
+class SalBitmap;
+class SalFrame;
+class Gradient;
+class SalVirtualDevice;
+
+class VCL_PLUGIN_PUBLIC SalGraphicsImpl
+{
+public:
+
+ virtual ~SalGraphicsImpl();
+
+ virtual void freeResources() = 0;
+
+ virtual bool setClipRegion( const vcl::Region& ) = 0;
+ //
+ // get the depth of the device
+ virtual sal_uInt16 GetBitCount() const = 0;
+
+ // get the width of the device
+ virtual long GetGraphicsWidth() const = 0;
+
+ // set the clip region to empty
+ virtual void ResetClipRegion() = 0;
+
+ // set the line color to transparent (= don't draw lines)
+
+ virtual void SetLineColor() = 0;
+
+ // set the line color to a specific color
+ virtual void SetLineColor( SalColor nSalColor ) = 0;
+
+ // set the fill color to transparent (= don't fill)
+ virtual void SetFillColor() = 0;
+
+ // set the fill color to a specific color, shapes will be
+ // filled accordingly
+ virtual void SetFillColor( SalColor nSalColor ) = 0;
+
+ // enable/disable XOR drawing
+ virtual void SetXORMode( bool bSet, bool bInvertOnly ) = 0;
+
+ // set line color for raster operations
+ virtual void SetROPLineColor( SalROPColor nROPColor ) = 0;
+
+ // set fill color for raster operations
+ virtual void SetROPFillColor( SalROPColor nROPColor ) = 0;
+
+ // draw --> LineColor and FillColor and RasterOp and ClipRegion
+ virtual void drawPixel( long nX, long nY ) = 0;
+ virtual void drawPixel( long nX, long nY, SalColor nSalColor ) = 0;
+
+ virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) = 0;
+
+ virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) = 0;
+
+ virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;
+
+ virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;
+
+ virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) = 0;
+ virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) = 0;
+
+ virtual bool drawPolyLine(
+ const ::basegfx::B2DPolygon&,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin,
+ com::sun::star::drawing::LineCap) = 0;
+
+ virtual bool drawPolyLineBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) = 0;
+
+ virtual bool drawPolygonBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) = 0;
+
+ virtual bool drawPolyPolygonBezier(
+ sal_uInt32 nPoly,
+ const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry,
+ const sal_uInt8* const* pFlgAry ) = 0;
+
+ // CopyArea --> No RasterOp, but ClipRegion
+ virtual void copyArea(
+ long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 nFlags ) = 0;
+
+ // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+ // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+ virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) = 0;
+
+ virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) = 0;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor ) = 0;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap ) = 0;
+
+ virtual void drawMask(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor ) = 0;
+
+ virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) = 0;
+
+ virtual SalColor getPixel( long nX, long nY ) = 0;
+
+ // invert --> ClipRegion (only Windows or VirDevs)
+ virtual void invert(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags) = 0;
+
+ virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) = 0;
+
+ virtual bool drawEPS(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ void* pPtr,
+ sal_uLong nSize ) = 0;
+
+ /** Render bitmap with alpha channel
+
+ @param rSourceBitmap
+ Source bitmap to blit
+
+ @param rAlphaBitmap
+ Alpha channel to use for blitting
+
+ @return true, if the operation succeeded, and false
+ otherwise. In this case, clients should try to emulate alpha
+ compositing themselves
+ */
+ virtual bool drawAlphaBitmap(
+ const SalTwoRect&,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap& rAlphaBitmap ) = 0;
+
+ /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+ virtual bool drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap) = 0;
+
+ /** Render solid rectangle with given transparency
+
+ @param nTransparency
+ Transparency value (0-255) to use. 0 blits and opaque, 255 a
+ fully transparent rectangle
+ */
+ virtual bool drawAlphaRect(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency ) = 0;
+
+ virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0;
+
+ virtual bool swapBuffers() = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx
new file mode 100644
index 000000000000..f4dcc8358cb1
--- /dev/null
+++ b/vcl/inc/textrender.hxx
@@ -0,0 +1,81 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_CAIROFONTIMPL_HXX
+#define INCLUDED_VCL_INC_UNX_CAIROFONTIMPL_HXX
+
+#include <sal/types.h>
+#include <vcl/salgtype.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/metric.hxx>
+
+#include "salgdi.hxx"
+#include "salglyphid.hxx"
+#include "fontsubset.hxx"
+
+class PspSalPrinter;
+class PspSalInfoPrinter;
+class ServerFont;
+class ImplLayoutArgs;
+class ServerFontLayout;
+class PhysicalFontCollection;
+class PhysicalFontFace;
+
+class TextRenderImpl
+{
+public:
+ virtual ~TextRenderImpl() {}
+
+ virtual void SetTextColor( SalColor nSalColor ) = 0;
+ virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) = 0;
+ virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) = 0;
+ virtual const FontCharMapPtr GetFontCharMap() const = 0;
+ virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const = 0;
+ virtual void GetDevFontList( PhysicalFontCollection* ) = 0;
+ virtual void ClearDevFontCache() = 0;
+ virtual bool AddTempDevFont( PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) = 0;
+ virtual bool CreateFontSubset( const OUString& rToFile,
+ const PhysicalFontFace*,
+ sal_GlyphId* pGlyphIDs,
+ sal_uInt8* pEncoding,
+ sal_Int32* pWidths,
+ int nGlyphs,
+ FontSubsetInfo& rInfo
+ ) = 0;
+ virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded ) = 0;
+ virtual const void* GetEmbedFontData( const PhysicalFontFace*,
+ const sal_Ucs* pUnicodes,
+ sal_Int32* pWidths,
+ FontSubsetInfo& rInfo,
+ long* pDataLen ) = 0;
+ virtual void FreeEmbedFontData( const void* pData, long nDataLen ) = 0;
+ virtual void GetGlyphWidths( const PhysicalFontFace*,
+ bool bVertical,
+ Int32Vector& rWidths,
+ Ucs2UIntMap& rUnicodeEnc ) = 0;
+ virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0;
+ virtual bool GetGlyphOutline( sal_GlyphId nIndex, ::basegfx::B2DPolyPolygon& ) = 0;
+ virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
+ virtual void DrawServerFontLayout( const ServerFontLayout& ) = 0;
+ virtual SystemFontData GetSysFontData( int nFallbackLevel ) const = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 93a7f1dccb1c..c10f0b5687f9 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -33,6 +33,7 @@
#include <salframe.hxx>
#include <vcl/sysdata.hxx>
+#include <unx/x11windowprovider.hxx>
#include <unx/saltype.h>
#include "tools/link.hxx"
@@ -58,7 +59,7 @@ typedef ::Window GdkNativeWindow;
typedef void GDBusConnection;
#endif
-class GtkSalFrame : public SalFrame
+class GtkSalFrame : public SalFrame, public X11WindowProvider
{
static const int nMaxGraphics = 2;
@@ -445,6 +446,8 @@ public:
static GtkSalFrame *getFromWindow( GtkWindow *pWindow );
virtual void damaged (const basegfx::B2IBox& rDamageRect);
+
+ virtual Window GetX11Window() SAL_OVERRIDE;
};
#define OOO_TYPE_FIXED ooo_fixed_get_type()
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index b8b145b218d0..05d763caaae8 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -114,6 +114,7 @@ private:
#else
+class GdkX11Pixmap;
class GtkSalGraphics : public X11SalGraphics
{
GtkWidget *m_pWindow;
@@ -162,8 +163,8 @@ public:
protected:
typedef std::list< Rectangle > clipList;
- GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect );
- bool NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect );
+ GdkX11Pixmap* NWGetPixmapFromScreen( Rectangle srcRect );
+ bool NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect );
bool NWPaintGTKArrow( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
const Rectangle& rControlRectangle,
diff --git a/vcl/inc/unx/pixmap.hxx b/vcl/inc/unx/pixmap.hxx
new file mode 100644
index 000000000000..40bc11f0d0bf
--- /dev/null
+++ b/vcl/inc/unx/pixmap.hxx
@@ -0,0 +1,46 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+#define INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+
+#include <prex.h>
+#include <postx.h>
+#include <tools/gen.hxx>
+#include <unx/saltype.h>
+#include <vclpluginapi.h>
+
+class VCLPLUG_GEN_PUBLIC X11Pixmap
+{
+public:
+ X11Pixmap();
+ X11Pixmap( Display *pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth );
+ X11Pixmap( X11Pixmap& rOther );
+ virtual ~X11Pixmap();
+
+ Pixmap GetPixmap() const { return mpPixmap; };
+ Drawable GetDrawable() const { return mpPixmap; };
+ int GetWidth() const { return mnWidth; };
+ int GetHeight() const { return mnHeight; };
+ Size GetSize() const { return Size( mnWidth, mnHeight ); };
+ int GetDepth() const { return mnDepth; };
+ SalX11Screen GetScreen() const { return mnScreen; }
+
+protected:
+ Display* mpDisplay;
+ SalX11Screen mnScreen;
+ Pixmap mpPixmap;
+ int mnWidth;
+ int mnHeight;
+ int mnDepth;
+};
+
+#endif // INCLUDED_VCL_INC_UNX_PIXMAP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/salbmp.h b/vcl/inc/unx/salbmp.h
index f6cadaab8145..f3f08313e585 100644
--- a/vcl/inc/unx/salbmp.h
+++ b/vcl/inc/unx/salbmp.h
@@ -145,6 +145,8 @@ public:
virtual BitmapBuffer* AcquireBuffer( bool bReadOnly ) SAL_OVERRIDE;
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) SAL_OVERRIDE;
virtual bool GetSystemData( BitmapSystemData& rData ) SAL_OVERRIDE;
+
+ virtual bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) SAL_OVERRIDE;
};
// - ImplSalDDB -
diff --git a/vcl/inc/unx/salframe.h b/vcl/inc/unx/salframe.h
index 637ef677a221..9b737f9aeca1 100644
--- a/vcl/inc/unx/salframe.h
+++ b/vcl/inc/unx/salframe.h
@@ -26,6 +26,7 @@
#include <unx/salunx.h>
#include <unx/saltype.h>
#include <unx/saldisp.hxx>
+#include <unx/x11windowprovider.hxx>
#include <salframe.hxx>
#include <salwtype.hxx>
#include <salinst.hxx>
@@ -48,7 +49,7 @@ namespace vcl_sal { class WMAdaptor; class NetWMAdaptor; class GnomeWMAdaptor; }
#define SHOWSTATE_NORMAL 1
#define SHOWSTATE_HIDDEN 2
-class VCLPLUG_GEN_PUBLIC X11SalFrame : public SalFrame
+class VCLPLUG_GEN_PUBLIC X11SalFrame : public SalFrame, public X11WindowProvider
{
friend class vcl_sal::WMAdaptor;
friend class vcl_sal::NetWMAdaptor;
@@ -270,6 +271,8 @@ public:
// done setting up the clipregion
virtual void EndSetClipRegion() SAL_OVERRIDE;
+ virtual Window GetX11Window() SAL_OVERRIDE;
+
static Bool checkKeyReleaseForRepeat( Display*, XEvent*, XPointer pX11SalFrame );
/// @internal
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index f56411227405..8a5cc0c43bae 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -32,6 +32,8 @@
#include "sallayout.hxx"
#include "vclpluginapi.h"
+#include <boost/scoped_ptr.hpp>
+
#include <deque>
class ImplFontMetricData;
@@ -40,8 +42,10 @@ class SalBitmap;
class SalColormap;
class SalDisplay;
class SalFrame;
+class X11Pixmap;
class X11SalVirtualDevice;
-class SalPolyLine;
+class X11SalGraphicsImpl;
+class X11OpenGLSalGraphicsImpl;
class PspSalPrinter;
class PspSalInfoPrinter;
class ServerFont;
@@ -49,44 +53,24 @@ class ImplLayoutArgs;
class ServerFontLayout;
class PhysicalFontCollection;
class PhysicalFontFace;
+class SalGraphicsImpl;
+class TextRenderImpl;
namespace basegfx {
class B2DTrapezoid;
}
-typedef struct FT_FaceRec_* FT_Face;
-
-class CairoFontsCache
+class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
{
-public:
- struct CacheId
- {
- FT_Face maFace;
- const void *mpOptions;
- bool mbEmbolden;
- bool mbVerticalMetrics;
- bool operator ==(const CacheId& rOther) const
- {
- return maFace == rOther.maFace &&
- mpOptions == rOther.mpOptions &&
- mbEmbolden == rOther.mbEmbolden &&
- mbVerticalMetrics == rOther.mbVerticalMetrics;
- }
- };
+ friend class ServerFontLayout;
+ friend class X11SalGraphicsImpl;
+ friend class X11OpenGLSalGraphicsImpl;
+ friend class X11CairoTextRender;
+
private:
- static int mnRefCount;
- typedef std::deque< std::pair<void *, CacheId> > LRUFonts;
- static LRUFonts maLRUFonts;
-public:
- CairoFontsCache();
- static void CacheFont(void *pFont, const CacheId &rId);
- static void* FindCachedFont(const CacheId &rId);
- ~CairoFontsCache();
-};
+ boost::scoped_ptr<SalGraphicsImpl> mpImpl;
+ boost::scoped_ptr<TextRenderImpl> mpTextRenderImpl;
-class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
-{
- friend class ServerFontLayout;
protected:
SalFrame* m_pFrame; // the SalFrame which created this Graphics or NULL
X11SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
@@ -97,72 +81,26 @@ protected:
SalX11Screen m_nXScreen;
mutable XRenderPictFormat* m_pXRenderFormat;
XID m_aXRenderPicture;
- CairoFontsCache m_aCairoFontsCache;
Region pPaintRegion_;
Region mpClipRegion;
- GC pPenGC_; // Pen attributes
- SalColor nPenColor_;
- Pixel nPenPixel_;
-
GC pFontGC_; // Font attributes
- ServerFont* mpServerFont[ MAX_FALLBACK ];
+ Pixel nTextPixel_;
- SalColor nTextColor_;
- Pixel nTextPixel_;
-
- bool bDisableGraphite_;
-
- GC pBrushGC_; // Brush attributes
- SalColor nBrushColor_;
- Pixel nBrushPixel_;
Pixmap hBrush_; // Dither
- GC pMonoGC_;
- GC pCopyGC_;
- GC pMaskGC_;
- GC pInvertGC_;
- GC pInvert50GC_;
- GC pStippleGC_;
- GC pTrackingGC_;
-
bool bWindow_ : 1; // is Window
bool bPrinter_ : 1; // is Printer
bool bVirDev_ : 1; // is VirDev
- bool bPenGC_ : 1; // is Pen GC valid
- bool bFontGC_ : 1; // is Font GC valid
- bool bBrushGC_ : 1; // is Brush GC valid
- bool bMonoGC_ : 1; // is Mono GC valid
- bool bCopyGC_ : 1; // is Copy GC valid
- bool bInvertGC_ : 1; // is Invert GC valid
- bool bInvert50GC_ : 1; // is Invert50 GC valid
- bool bStippleGC_ : 1; // is Stipple GC valid
- bool bTrackingGC_ : 1; // is Tracking GC valid
- bool bXORMode_ : 1; // is ROP XOR Mode set
- bool bDitherBrush_ : 1; // is solid or tile
+ bool bFontGC_ : 1; // is Font GC valid
using SalGraphics::SetClipRegion;
void SetClipRegion( GC pGC,
Region pXReg = NULL ) const;
- GC GetTrackingGC();
- GC GetInvertGC();
- GC GetInvert50GC();
- GC CreateGC( Drawable hDrawable,
- unsigned long nMask = GCGraphicsExposures );
- GC SelectPen();
- GC SelectBrush();
- void DrawLines( sal_uIntPtr nPoints,
- const SalPolyLine &rPoints,
- GC pGC,
- bool bClose
- );
bool GetDitherPixmap ( SalColor nSalColor );
- inline GC GetMonoGC( Pixmap hPixmap );
- inline GC GetCopyGC();
- inline GC GetStippleGC();
using SalGraphics::DrawBitmap;
void DrawBitmap( const SalTwoRect& rPosAry,
@@ -172,11 +110,6 @@ protected:
SalColor nTransparentColor );
GC GetFontGC();
- bool setFont( const FontSelectPattern* pEntry, int nFallbackLevel );
-
- void drawMaskedBitmap( const SalTwoRect& rPosAry,
- const SalBitmap& rSalBitmap,
- const SalBitmap& rTransparentBitmap );
protected:
void DrawPrinterString( const SalLayout& );
@@ -198,12 +131,11 @@ public:
inline const SalVisual& GetVisual() const;
inline Drawable GetDrawable() const { return hDrawable_; }
void SetDrawable( Drawable d, SalX11Screen nXScreen );
- XID GetXRenderPicture();
XRenderPictFormat* GetXRenderFormat() const;
inline void SetXRenderFormat( XRenderPictFormat* pXRenderFormat ) { m_pXRenderFormat = pXRenderFormat; }
inline const SalColormap& GetColormap() const { return *m_pColormap; }
using SalGraphics::GetPixel;
- inline Pixel GetPixel( SalColor nSalColor ) const;
+ inline Pixel GetPixel( SalColor nSalColor ) const;
SalX11Screen GetScreenNumber() const { return m_nXScreen; }
@@ -211,7 +143,6 @@ public:
virtual void GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) SAL_OVERRIDE;
virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE;
virtual long GetGraphicsWidth() const SAL_OVERRIDE;
- virtual long GetGraphicsHeight() const;
virtual void ResetClipRegion() SAL_OVERRIDE;
virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
@@ -263,7 +194,6 @@ public:
virtual void drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
- void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
virtual void drawPolyPolygon( sal_uInt32 nPoly,
@@ -276,9 +206,7 @@ public:
const ::basegfx::B2DVector& rLineWidth,
basegfx::B2DLineJoin,
com::sun::star::drawing::LineCap) SAL_OVERRIDE;
- virtual bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
- virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) SAL_OVERRIDE { return false; };
-
+ virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) SAL_OVERRIDE;
#if 1 // TODO: remove these obselete methods
virtual bool drawPolyLineBezier( sal_uInt32 nPoints,
@@ -334,7 +262,16 @@ public:
long nHeight, sal_uInt8 nTransparency ) SAL_OVERRIDE;
virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE;
- virtual SystemFontData GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE;
+ virtual SystemFontData GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE;
+
+ virtual bool SwapBuffers() SAL_OVERRIDE;
+
+ // create a pixmap from a screen region
+ X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect );
+
+ // render a pixmap to the screen
+ bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY );
+
/* use to handle GraphicsExpose/NoExpose after XCopyArea & friends
* if pFrame is not NULL, corresponding Paint events are generated
diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h
new file mode 100644
index 000000000000..911ea71e8ed3
--- /dev/null
+++ b/vcl/inc/unx/x11/x11gdiimpl.h
@@ -0,0 +1,27 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+#define INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+
+#include "unx/pixmap.hxx"
+
+class X11GraphicsImpl
+{
+public:
+ virtual ~X11GraphicsImpl() {};
+
+ virtual void Init() = 0;
+ virtual X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) = 0;
+ virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0;
+};
+
+#endif // INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/x11windowprovider.hxx b/vcl/inc/unx/x11windowprovider.hxx
new file mode 100644
index 000000000000..776c8e4c4b34
--- /dev/null
+++ b/vcl/inc/unx/x11windowprovider.hxx
@@ -0,0 +1,28 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_UNX_X11WINDOWPROVIDER
+#define INCLUDED_VCL_UNX_X11WINDOWPROVIDER
+
+#include <prex.h>
+#include <postx.h>
+
+#include <vcl/dllapi.h>
+
+class VCL_PLUGIN_PUBLIC X11WindowProvider
+{
+public:
+ virtual ~X11WindowProvider();
+
+ virtual Window GetX11Window() = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/win/salbmp.h b/vcl/inc/win/salbmp.h
index 0962facb7e0c..90382363b3e5 100644
--- a/vcl/inc/win/salbmp.h
+++ b/vcl/inc/win/salbmp.h
@@ -96,6 +96,8 @@ public:
virtual BitmapBuffer* AcquireBuffer( bool bReadOnly );
virtual void ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly );
virtual bool GetSystemData( BitmapSystemData& rData );
+
+ virtual bool Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag );
};
#endif // INCLUDED_VCL_INC_WIN_SALBMP_H
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index ca423fb46f8d..f09af2813e79 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -40,6 +40,7 @@ class FontSelectPattern;
class ImplWinFontEntry;
class ImplFontAttrCache;
class PhysicalFontCollection;
+class SalGraphicsImpl;
#define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000)
#define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff)
@@ -143,29 +144,28 @@ public:
class WinSalGraphics : public SalGraphics
{
+ friend class WinSalGraphicsImpl;
+ friend class ScopedFont;
private:
- HDC mhLocalDC; // HDC
-
-public:
- HDC getHDC() const { return mhLocalDC; }
- void setHDC(HDC aNew) { mhLocalDC = aNew; }
+ boost::scoped_ptr<SalGraphicsImpl> mpImpl;
-public:
+ HDC mhLocalDC; // HDC
+ bool mbPrinter : 1; // is Printer
+ bool mbVirDev : 1; // is VirDev
+ bool mbWindow : 1; // is Window
+ bool mbScreen : 1; // is Screen compatible
HWND mhWnd; // Window-Handle, when Window-Graphics
+
HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks
const ImplWinFontData* mpWinFontData[ MAX_FALLBACK ]; // pointer to the most recent font face
ImplWinFontEntry* mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance
float mfFontScale[ MAX_FALLBACK ]; // allows metrics emulation of huge font sizes
float mfCurrentFontScale;
- HPEN mhPen; // Pen
- HBRUSH mhBrush; // Brush
HRGN mhRegion; // vcl::Region Handle
HPEN mhDefPen; // DefaultPen
HBRUSH mhDefBrush; // DefaultBrush
HFONT mhDefFont; // DefaultFont
HPALETTE mhDefPal; // DefaultPalette
- COLORREF mnPenColor; // PenColor
- COLORREF mnBrushColor; // BrushColor
COLORREF mnTextColor; // TextColor
RGNDATA* mpClipRgnData; // ClipRegion-Data
RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
@@ -178,27 +178,43 @@ public:
sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of the current Font
int mnPenWidth; // Linienbreite
- /// bitfield
- bool mbStockPen : 1; // is Pen a stockpen
- bool mbStockBrush : 1; // is Brush a stcokbrush
- bool mbPen : 1; // is Pen (FALSE == NULL_PEN)
- bool mbBrush : 1; // is Brush (FALSE == NULL_BRUSH)
- bool mbPrinter : 1; // is Printer
- bool mbVirDev : 1; // is VirDev
- bool mbWindow : 1; // is Window
- bool mbScreen : 1; // is Screen compatible
- bool mbXORMode : 1; // _every_ output with RasterOp XOR
+public:
+ HDC getHDC() const { return mhLocalDC; }
+ void setHDC(HDC aNew) { mhLocalDC = aNew; }
+
+ HPALETTE getDefPal() const;
+ void setDefPal(HPALETTE hDefPal);
+
+ HRGN getRegion() const;
+
+ void InitGraphics();
+ void DeInitGraphics();
- // remember RGB values for SetLineColor/SetFillColor
- SalColor maLineColor;
- SalColor maFillColor;
+ enum Type
+ {
+ PRINTER,
+ VIRTUAL_DEVICE,
+ WINDOW,
+ SCREEN
+ };
+
+public:
+
+ HWND gethWnd();
HFONT ImplDoSetFont( FontSelectPattern* i_pFont, float& o_rFontScale, HFONT& o_rOldFont );
public:
- explicit WinSalGraphics();
+ explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd);
virtual ~WinSalGraphics();
+ bool isPrinter() const;
+ bool isVirtualDevice() const;
+ bool isWindow() const;
+ bool isScreen() const;
+
+ void setHWND(HWND hWnd);
+
protected:
virtual bool setClipRegion( const vcl::Region& );
// draw --> LineColor and FillColor and RasterOp and ClipRegion
@@ -271,7 +287,6 @@ protected:
private:
// local helpers
- bool tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap);
// get kernign pairs of the current font
sal_uLong GetKernPairs();
@@ -382,13 +397,13 @@ public:
virtual SystemGraphicsData GetGraphicsData() const;
virtual SystemFontData GetSysFontData( int nFallbacklevel ) const;
+ virtual bool SwapBuffers() SAL_OVERRIDE;
+
/// Update settings based on the platform values
static void updateSettingsNative( AllSettings& rSettings );
};
// Init/Deinit Graphics
-void ImplSalInitGraphics( WinSalGraphics* );
-void ImplSalDeInitGraphics( WinSalGraphics* );
void ImplUpdateSysColorEntries();
int ImplIsSysColorEntry( SalColor nSalColor );
void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*,
diff --git a/vcl/inc/win/svsys.h b/vcl/inc/win/svsys.h
index 5554da9e0b0c..9753a8789025 100644
--- a/vcl/inc/win/svsys.h
+++ b/vcl/inc/win/svsys.h
@@ -21,9 +21,12 @@
#define INCLUDED_VCL_INC_WIN_SVSYS_H
#ifdef WNT
+#ifndef INCLUDED_PRE_POST_WIN_H
+#define INCLUDED_PRE_POST_WIN_H
#include <prewin.h>
#include <postwin.h>
#endif
+#endif
#endif // INCLUDED_VCL_INC_WIN_SVSYS_H
diff --git a/chart2/opengl/README.deprecated b/vcl/opengl/README.deprecated
index eb033a0fde41..eb033a0fde41 100644
--- a/chart2/opengl/README.deprecated
+++ b/vcl/opengl/README.deprecated
diff --git a/vcl/opengl/convolutionFragmentShader.glsl b/vcl/opengl/convolutionFragmentShader.glsl
new file mode 100644
index 000000000000..d4f78027faa3
--- /dev/null
+++ b/vcl/opengl/convolutionFragmentShader.glsl
@@ -0,0 +1,28 @@
+/* -*- 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 vec2 offsets[16];
+uniform float kernel[16];
+
+varying vec2 tex_coord;
+
+void main(void)
+{
+ vec4 sum = texture2D(sampler, tex_coord.st) * kernel[0];
+ for (int i = 1; i < 16; i++) {
+ sum += texture2D(sampler, tex_coord.st - offsets[i]) * kernel[i];
+ sum += texture2D(sampler, tex_coord.st + offsets[i]) * kernel[i];
+ }
+ gl_FragColor = sum;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
new file mode 100644
index 000000000000..7094727c25d1
--- /dev/null
+++ b/vcl/opengl/gdiimpl.cxx
@@ -0,0 +1,1000 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "openglgdiimpl.hxx"
+
+#include <vcl/gradient.hxx>
+#include <salframe.hxx>
+#include "salvd.hxx"
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontriangulator.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <basegfx/polygon/b2dtrapezoid.hxx>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include "opengl/salbmp.hxx"
+
+#include <vector>
+
+#define GL_ATTRIB_POS 0
+#define GL_ATTRIB_TEX 1
+
+#define glUniformColor(nUniform, nColor, nTransparency) \
+ glUniform4f( nUniform, \
+ ((float) SALCOLOR_RED( nColor )) / 255, \
+ ((float) SALCOLOR_GREEN( nColor )) / 255, \
+ ((float) SALCOLOR_BLUE( nColor )) / 255, \
+ (100 - nTransparency) * (1.0 / 100) )
+
+#define glUniformColorf(nUniform, nColor, fTransparency) \
+ glUniform4f( nUniform, \
+ ((float) SALCOLOR_RED( nColor )) / 255, \
+ ((float) SALCOLOR_GREEN( nColor )) / 255, \
+ ((float) SALCOLOR_BLUE( nColor )) / 255, \
+ (1.0f - fTransparency) )
+
+OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
+{
+}
+
+void OpenGLSalGraphicsImpl::freeResources()
+{
+ // Delete shaders, programs and textures if not shared
+}
+
+bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
+{
+ const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
+
+ SAL_INFO( "vcl.opengl", "::setClipRegion" );
+
+ /*maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ glEnable( GL_STENCIL_TEST );
+
+ glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
+ glStencilMask( 0xFF );
+ glStencilFunc( GL_NEVER, 1, 0xFF );
+ glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
+
+ glClear( GL_STENCIL_BUFFER_BIT );
+ BeginSolid( SALCOLOR_NONE );
+ DrawPolyPolygon( aClip );
+ EndSolid();
+
+ glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
+ glStencilMask( 0x00 );
+ glStencilFunc( GL_EQUAL, 1, 0xFF );*/
+
+ return true;
+}
+
+// set the clip region to empty
+void OpenGLSalGraphicsImpl::ResetClipRegion()
+{
+ SAL_INFO( "vcl.opengl", "::ResetClipRegion" );
+ maContext.makeCurrent();
+ glDisable(GL_STENCIL_TEST);
+}
+
+// get the depth of the device
+sal_uInt16 OpenGLSalGraphicsImpl::GetBitCount() const
+{
+ return 32;
+}
+
+// get the width of the device
+long OpenGLSalGraphicsImpl::GetGraphicsWidth() const
+{
+ return GetWidth();
+}
+
+// set the line color to transparent (= don't draw lines)
+void OpenGLSalGraphicsImpl::SetLineColor()
+{
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ mnLineColor = SALCOLOR_NONE;
+ }
+}
+
+// set the line color to a specific color
+void OpenGLSalGraphicsImpl::SetLineColor( SalColor nSalColor )
+{
+ if( mnLineColor != nSalColor )
+ {
+ mnLineColor = nSalColor;
+ }
+}
+
+// set the fill color to transparent (= don't fill)
+void OpenGLSalGraphicsImpl::SetFillColor()
+{
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ mnFillColor = SALCOLOR_NONE;
+ }
+}
+
+// set the fill color to a specific color, shapes will be
+// filled accordingly
+void OpenGLSalGraphicsImpl::SetFillColor( SalColor nSalColor )
+{
+ if( mnFillColor != nSalColor )
+ {
+ mnFillColor = nSalColor;
+ }
+}
+
+// enable/disable XOR drawing
+void OpenGLSalGraphicsImpl::SetXORMode( bool /*bSet*/, bool /*bInvertOnly*/ )
+{
+}
+
+// set line color for raster operations
+void OpenGLSalGraphicsImpl::SetROPLineColor( SalROPColor /*nROPColor*/ )
+{
+}
+
+// set fill color for raster operations
+void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
+{
+}
+
+bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
+{
+ mnSolidProgram = OpenGLHelper::LoadShaders( "solidVertexShader", "solidFragmentShader" );
+ if( mnSolidProgram == 0 )
+ return false;
+
+ SAL_INFO( "vcl.opengl", "Solid Program Created" );
+ glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" );
+ mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
+{
+ mnTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "textureFragmentShader" );
+ if( mnTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
+{
+ mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskedTextureVertexShader", "maskedTextureFragmentShader" );
+ if( mnMaskedTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" );
+ mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" );
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
+{
+ mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
+ if( mnMaskedTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" );
+ mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "mask" );
+ return true;
+}
+
+void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency )
+{
+ if( mnSolidProgram == 0 )
+ {
+ glClearColor( 1, 1, 1, 1 );
+ glClear( GL_COLOR_BUFFER_BIT );
+ if( !CreateSolidProgram() )
+ return;
+ }
+
+ if( nTransparency > 0 )
+ {
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ }
+ glUseProgram( mnSolidProgram );
+ glUniformColor( mnColorUniform, nColor, nTransparency );
+}
+
+void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, double fTransparency )
+{
+ if( mnSolidProgram == 0 )
+ {
+ if( !CreateSolidProgram() )
+ return;
+ }
+
+ if( fTransparency > 0.0f )
+ {
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ }
+ glUseProgram( mnSolidProgram );
+ glUniformColorf( mnColorUniform, nColor, fTransparency );
+}
+
+void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor )
+{
+ BeginSolid( nColor, 0.0f );
+}
+
+void OpenGLSalGraphicsImpl::EndSolid( void )
+{
+ glUseProgram( 0 );
+ glDisable( GL_BLEND );
+}
+
+void OpenGLSalGraphicsImpl::BeginInvert( void )
+{
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
+ BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) );
+}
+
+void OpenGLSalGraphicsImpl::EndInvert( void )
+{
+ EndSolid();
+ glDisable( GL_BLEND );
+}
+
+void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
+{
+ GLfloat pPoint[2];
+
+ pPoint[0] = 2 * nX / GetWidth() - 1.0f;
+ pPoint[1] = 2 * (GetHeight() - nY) / GetHeight() - 1.0f;
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, pPoint );
+ glDrawArrays( GL_POINTS, 0, 1 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ GLfloat pPoints[4];
+
+ pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
+ pPoints[1] = (2 * (GetHeight() - nY1)) / GetHeight() - 1.0;
+ pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
+ pPoints[3] = (2 * (GetHeight() - nY2)) / GetHeight() - 1.0;
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoints );
+ glDrawArrays( GL_LINES, 0, 2 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
+{
+ std::vector<GLfloat> aPoints(nPoints * 2);
+ sal_uInt32 i, j;
+
+ for( i = 0, j = 0; i < nPoints; i++ )
+ {
+ aPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0f;
+ aPoints[j++] = 1.0f - (2 * pPtAry[i].mnY) / GetHeight();
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aPoints[0] );
+ if( bClose )
+ glDrawArrays( GL_LINE_LOOP, 0, nPoints );
+ else
+ glDrawArrays( GL_LINE_STRIP, 0, nPoints );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ std::vector<GLfloat> aVertices(nPoints * 2);
+ sal_uInt32 i, j;
+
+ for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+ {
+ aVertices[j] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0;
+ aVertices[j+1] = (2 * pPtAry[i].mnY) / GetHeight() - 1.0;
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ long nX1( nX );
+ long nY1( GetHeight() - nY );
+ long nX2( nX + nWidth );
+ long nY2( GetHeight() - nY - nHeight );
+ const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
+ { nX2, nY1 }, { nX2, nY2 }};
+
+ DrawConvexPolygon( 4, aPoints );
+}
+
+void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ ::basegfx::B2DPolygon aPolygon;
+
+ for( sal_uInt32 i = 0; i < nPoints; i++ )
+ aPolygon.append( ::basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
+ aPolygon.setClosed( true );
+
+ if( ::basegfx::tools::isConvex( aPolygon ) )
+ {
+ if( nPoints > 2L )
+ DrawConvexPolygon( nPoints, pPtAry );
+ }
+ else
+ {
+ const ::basegfx::B2DPolyPolygon aPolyPolygon( aPolygon );
+ DrawPolyPolygon( aPolyPolygon );
+ }
+}
+
+void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon )
+{
+ sal_uInt32 i, j;
+ ::std::vector< GLfloat > pVertices;
+ GLfloat nWidth = GetWidth();
+ GLfloat nHeight = GetHeight();
+ const ::basegfx::B2DPolyPolygon& aSimplePolyPolygon = ::basegfx::tools::solveCrossovers( rPolyPolygon );
+
+ for( i = 0; i < aSimplePolyPolygon.count(); i++ )
+ {
+ const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) );
+ const ::basegfx::B2DPolygon& aResult(
+ ::basegfx::triangulator::triangulate( rPolygon ) );
+
+ for( j = 0; j < aResult.count(); j++ )
+ {
+ const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint( j ) );
+ pVertices.push_back( 2 * rPt.getX() / nWidth - 1.0f );
+ pVertices.push_back( 1.0f - 2 * rPt.getY() / nHeight );
+ }
+ }
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pVertices.data() );
+ glDrawArrays( GL_TRIANGLES, 0, pVertices.size() / 2 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+}
+
+void OpenGLSalGraphicsImpl::DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry )
+{
+ GLfloat aTexCoord[8];
+
+ aTexCoord[0] = aTexCoord[2] = rPosAry.mnSrcX / (double) rSize.Width();
+ aTexCoord[4] = aTexCoord[6] = (rPosAry.mnSrcX + rPosAry.mnSrcWidth) / (double) rSize.Width();
+ aTexCoord[3] = aTexCoord[5] = (rSize.Height() - rPosAry.mnSrcY) / (double) rSize.Height();
+ aTexCoord[1] = aTexCoord[7] = (rSize.Height() - rPosAry.mnSrcY - rPosAry.mnSrcHeight) / (double) rSize.Height();
+
+ glEnableVertexAttribArray( GL_ATTRIB_TEX );
+ glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
+
+ DrawRect( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight );
+
+ glDisableVertexAttribArray( GL_ATTRIB_TEX );
+}
+
+void OpenGLSalGraphicsImpl::DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& pPosAry )
+{
+ if( mnTextureProgram == 0 )
+ {
+ if( !CreateTextureProgram() )
+ return;
+ }
+
+ glUseProgram( mnTextureProgram );
+ glUniform1i( mnSamplerUniform, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ CHECK_GL_ERROR();
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+
+ DrawTextureRect( rSize, pPosAry );
+ CHECK_GL_ERROR();
+
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
+}
+
+void OpenGLSalGraphicsImpl::DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& pPosAry )
+{
+ if( mnMaskedTextureProgram == 0 )
+ {
+ if( !CreateMaskedTextureProgram() )
+ return;
+ }
+
+ glUseProgram( mnMaskedTextureProgram );
+ glUniform1i( mnMaskedSamplerUniform, 0 );
+ glUniform1i( mnMaskSamplerUniform, 1 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, nMask );
+
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ DrawTextureRect( rSize, pPosAry );
+ glDisable( GL_BLEND );
+
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
+}
+
+void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& /*pPosAry*/ )
+{
+ if( mnMaskProgram == 0 )
+ {
+ if( !CreateMaskProgram() )
+ return;
+ }
+
+ glUseProgram( mnMaskProgram );
+ glUniformColor( mnMaskColorUniform, nMaskColor, 0 );
+ glUniform1i( mnMaskUniform, 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nMask );
+
+ //DrawTextureRect( pPosAry );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ glUseProgram( 0 );
+}
+
+
+// draw --> LineColor and FillColor and RasterOp and ClipRegion
+void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
+{
+ SAL_INFO( "vcl.opengl", "::drawPixel" );
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ BeginSolid( mnLineColor );
+ DrawPoint( nX, nY );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ SAL_INFO( "vcl.opengl", "::drawPixel" );
+ if( nSalColor != SALCOLOR_NONE )
+ {
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ BeginSolid( nSalColor );
+ DrawPoint( nX, nY );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ SAL_INFO( "vcl.opengl", "::drawLine" );
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ BeginSolid( mnLineColor );
+ DrawLine( nX1, nY1, nX2, nY2 );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ SAL_INFO( "vcl.opengl", "::drawRect" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ DrawRect( nX, nY, nWidth, nHeight );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ const long nX1( nX );
+ const long nY1( nY );
+ const long nX2( nX + nWidth - 1 );
+ const long nY2( nY + nHeight - 1 );
+ const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 },
+ { nX2, nY2 }, { nX1, nY2 } };
+
+ BeginSolid( mnLineColor );
+ DrawLines( 4, aPoints, true );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ SAL_INFO( "vcl.opengl", "::drawPolyLine" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
+ {
+ BeginSolid( mnLineColor );
+ DrawLines( nPoints, pPtAry, false );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ SAL_INFO( "vcl.opengl", "::drawPolygon" );
+ if( nPoints == 0 )
+ return;
+ if( nPoints == 1 )
+ {
+ drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ return;
+ }
+ if( nPoints == 2 )
+ {
+ drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ return;
+ }
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ DrawPolygon( nPoints, pPtAry );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnLineColor );
+ DrawLines( nPoints, pPtAry, true );
+ EndSolid();
+ }
+}
+
+void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry )
+{
+ SAL_INFO( "vcl.opengl", "::drawPolyPolygon" );
+ if( nPoly <= 0 )
+ return;
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor );
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ DrawPolygon( pPoints[i], pPtAry[i] );
+ EndSolid();
+ }
+
+ if( mnLineColor != SALCOLOR_NONE )
+ {
+ // TODO Use glMultiDrawElements or primitive restart
+ BeginSolid( mnLineColor );
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ DrawLines( pPoints[i], pPtAry[i], true );
+ EndSolid();
+ }
+}
+
+bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency )
+{
+ SAL_INFO( "vcl.opengl", "::drawPolyPolygon trans " << fTransparency );
+ if( rPolyPolygon.count() <= 0 )
+ return true;
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( mnFillColor != SALCOLOR_NONE )
+ {
+ BeginSolid( mnFillColor, fTransparency );
+ for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ )
+ {
+ const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) );
+ DrawPolyPolygon( aOnePoly );
+ }
+ EndSolid();
+ }
+
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::drawPolyLine(
+ const ::basegfx::B2DPolygon& rPolygon,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidth,
+ basegfx::B2DLineJoin eLineJoin,
+ com::sun::star::drawing::LineCap eLineCap)
+{
+ SAL_INFO( "vcl.opengl", "::drawPolyLine trans " << fTransparency );
+ if( mnLineColor == SALCOLOR_NONE )
+ return true;
+
+ const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2);
+
+ // #i101491#
+ if( !bIsHairline && (rPolygon.count() > 1000) )
+ {
+ // the used basegfx::tools::createAreaGeometry is simply too
+ // expensive with very big polygons; fallback to caller (who
+ // should use ImplLineConverter normally)
+ // AW: ImplLineConverter had to be removed since it does not even
+ // know LineJoins, so the fallback will now prepare the line geometry
+ // the same way.
+ return false;
+ }
+
+ // #i11575#desc5#b adjust B2D tesselation result to raster positions
+ basegfx::B2DPolygon aPolygon = rPolygon;
+ const double fHalfWidth = 0.5 * rLineWidth.getX();
+
+ // #i122456# This is probably thought to happen to align hairlines to pixel positions, so
+ // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines
+ aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) );
+
+ // shortcut for hairline drawing to improve performance
+ //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;*/
+ }
+
+ // get the area polygon for the line polygon
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
+ {
+ // prepare for createAreaGeometry() with anisotropic linewidth
+ aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
+ }
+
+ // create the area-polygon for the line
+ const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) );
+
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
+ {
+ // postprocess createAreaGeometry() for anisotropic linewidth
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
+ }
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ BeginSolid( mnLineColor, fTransparency );
+ for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ )
+ {
+ const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) );
+ DrawPolyPolygon( aOnePoly );
+ }
+ EndSolid();
+
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::drawPolyLineBezier(
+ sal_uInt32 /*nPoints*/,
+ const SalPoint* /*pPtAry*/,
+ const sal_uInt8* /*pFlgAry*/ )
+{
+ return false;
+}
+
+bool OpenGLSalGraphicsImpl::drawPolygonBezier(
+ sal_uInt32 /*nPoints*/,
+ const SalPoint* /*pPtAry*/,
+ const sal_uInt8* /*pFlgAry*/ )
+{
+ return false;
+}
+
+bool OpenGLSalGraphicsImpl::drawPolyPolygonBezier(
+ sal_uInt32 /*nPoly*/,
+ const sal_uInt32* /*pPoints*/,
+ const SalPoint* const* /*pPtAry*/,
+ const sal_uInt8* const* /*pFlgAry*/ )
+{
+ return NULL;
+}
+
+// CopyArea --> No RasterOp, but ClipRegion
+void OpenGLSalGraphicsImpl::copyArea(
+ long /*nDestX*/, long /*nDestY*/,
+ long /*nSrcX*/, long /*nSrcY*/,
+ long /*nSrcWidth*/, long /*nSrcHeight*/,
+ sal_uInt16 /*nFlags*/ )
+{
+ SAL_INFO( "vcl.opengl", "::copyArea" );
+}
+
+// CopyBits and DrawBitmap --> RasterOp and ClipRegion
+// CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+void OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* /*pSrcGraphics*/ )
+{
+ // TODO Check if SalGraphicsImpl is the same
+ const bool bSameGraphics( false );
+
+ SAL_INFO( "vcl.opengl", "::copyBits" );
+ if( bSameGraphics &&
+ (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
+ (rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
+ {
+ // short circuit if there is nothing to do
+ if( (rPosAry.mnSrcX == rPosAry.mnDestX) &&
+ (rPosAry.mnSrcY == rPosAry.mnDestY))
+ return;
+ // use copyArea() if source and destination context are identical
+ copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 );
+ return;
+ }
+
+ // TODO Copy from one FBO to the other (glBlitFramebuffer)
+}
+
+void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
+{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ GLuint nTexture = rBitmap.GetTexture( maContext );
+ const Size aSize = rSalBitmap.GetSize();
+
+ SAL_INFO( "vcl.opengl", "::drawBitmap" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ DrawTexture( nTexture, aSize, rPosAry );
+}
+
+void OpenGLSalGraphicsImpl::drawBitmap(
+ const SalTwoRect& /*rPosAry*/,
+ const SalBitmap& /*rSalBitmap*/,
+ SalColor /*nTransparentColor*/ )
+{
+ OSL_FAIL( "::DrawBitmap with transparent color not supported" );
+}
+
+void OpenGLSalGraphicsImpl::drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap )
+{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const OpenGLSalBitmap& rMask = static_cast<const OpenGLSalBitmap&>(rMaskBitmap);
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+ const GLuint nMask( rMask.GetTexture( maContext ) );
+
+ SAL_INFO( "vcl.opengl", "::drawBitmap with MASK" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ DrawTextureWithMask( nTexture, nMask, rBitmap.GetSize(), rPosAry );
+}
+
+void OpenGLSalGraphicsImpl::drawMask(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
+{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+
+ SAL_INFO( "vcl.opengl", "::drawMask" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ DrawMask( nTexture, nMaskColor, rPosAry );
+}
+
+SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long nHeight )
+{
+ OpenGLSalBitmap* pBitmap = new OpenGLSalBitmap;
+ SAL_INFO( "vcl.opengl", "::getBitmap " << nX << "," << nY <<
+ " " << nWidth << "x" << nHeight );
+ if( !pBitmap->Create( maContext, nX, nY, nWidth, nHeight ) )
+ {
+ delete pBitmap;
+ pBitmap = NULL;
+ }
+ return pBitmap;
+}
+
+SalColor OpenGLSalGraphicsImpl::getPixel( long nX, long nY )
+{
+ char pixel[3];
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ glReadPixels( nX, nY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
+ return MAKE_SALCOLOR( pixel[0], pixel[1], pixel[2] );
+}
+
+// invert --> ClipRegion (only Windows or VirDevs)
+void OpenGLSalGraphicsImpl::invert(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags)
+{
+ // TODO Figure out what are those:
+ // * SAL_INVERT_50 (50/50 pattern?)
+ // * SAL_INVERT_TRACKFRAME (dash-line rectangle?)
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+
+ }
+ else if( nFlags & SAL_INVERT_50 )
+ {
+
+ }
+ else // just invert
+ {
+ BeginInvert();
+ DrawRect( nX, nY, nWidth, nHeight );
+ EndInvert();
+ }
+}
+
+void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags )
+{
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ if( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+
+ }
+ else if( nFlags & SAL_INVERT_50 )
+ {
+
+ }
+ else // just invert
+ {
+ BeginInvert();
+ DrawPolygon( nPoints, pPtAry );
+ EndInvert();
+ }
+}
+
+bool OpenGLSalGraphicsImpl::drawEPS(
+ long /*nX*/, long /*nY*/,
+ long /*nWidth*/, long /*nHeight*/,
+ void* /*pPtr*/,
+ sal_uLong /*nSize*/ )
+{
+ return false;
+}
+
+/** Render bitmap with alpha channel
+
+ @param rSourceBitmap
+ Source bitmap to blit
+
+ @param rAlphaBitmap
+ Alpha channel to use for blitting
+
+ @return true, if the operation succeeded, and false
+ otherwise. In this case, clients should try to emulate alpha
+ compositing themselves
+ */
+bool OpenGLSalGraphicsImpl::drawAlphaBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rAlphaBitmap )
+{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ const OpenGLSalBitmap& rAlpha = static_cast<const OpenGLSalBitmap&>(rAlphaBitmap);
+ const GLuint nTexture( rBitmap.GetTexture( maContext ) );
+ const GLuint nAlpha( rAlpha.GetTexture( maContext ) );
+
+ SAL_INFO( "vcl.opengl", "::drawAlphaBitmap" );
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+ DrawTextureWithMask( nTexture, nAlpha, rBitmap.GetSize(), rPosAry );
+ return true;
+}
+
+/** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+bool OpenGLSalGraphicsImpl::drawTransformedBitmap(
+ const basegfx::B2DPoint& /*rNull*/,
+ const basegfx::B2DPoint& /*rX*/,
+ const basegfx::B2DPoint& /*rY*/,
+ const SalBitmap& /*rSourceBitmap*/,
+ const SalBitmap* /*pAlphaBitmap*/)
+{
+ return false;
+}
+
+/** Render solid rectangle with given transparency
+
+ @param nTransparency
+ Transparency value (0-255) to use. 0 blits and opaque, 255 a
+ fully transparent rectangle
+ */
+bool OpenGLSalGraphicsImpl::drawAlphaRect(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency )
+{
+ SAL_INFO( "vcl.opengl", "::drawAlphaRect" );
+ if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 )
+ {
+ BeginSolid( mnFillColor, nTransparency );
+ DrawRect( nX, nY, nWidth, nHeight );
+ EndSolid();
+ }
+
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
+ const Gradient& /*rGradient*/)
+{
+ return false;
+}
+
+bool OpenGLSalGraphicsImpl::swapBuffers()
+{
+ maContext.swapBuffers();
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskFragmentShader.glsl b/vcl/opengl/maskFragmentShader.glsl
new file mode 100644
index 000000000000..4a8204e6a663
--- /dev/null
+++ b/vcl/opengl/maskFragmentShader.glsl
@@ -0,0 +1,21 @@
+/* -*- 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/.
+ */
+
+precision mediump float;
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+uniform vec4 color;"
+
+void main() {
+ vec4 texel0;
+ texel0 = texture2D(sampler, tex_coord);
+ gl_FragColor = color * texel0.a;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskVertexShader.glsl b/vcl/opengl/maskVertexShader.glsl
new file mode 100644
index 000000000000..99d7f37eb05f
--- /dev/null
+++ b/vcl/opengl/maskVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskedTextureFragmentShader.glsl b/vcl/opengl/maskedTextureFragmentShader.glsl
new file mode 100644
index 000000000000..badf91e6edae
--- /dev/null
+++ b/vcl/opengl/maskedTextureFragmentShader.glsl
@@ -0,0 +1,23 @@
+/* -*- 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/.
+ */
+
+/*precision mediump float;*/
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+uniform sampler2D mask;
+
+void main() {
+ vec4 texel0, texel1;
+ texel0 = texture2D(sampler, tex_coord);
+ texel1 = texture2D(mask, tex_coord);
+ gl_FragColor = texel0;
+ gl_FragColor.a = texel1.r;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskedTextureVertexShader.glsl b/vcl/opengl/maskedTextureVertexShader.glsl
new file mode 100644
index 000000000000..99d7f37eb05f
--- /dev/null
+++ b/vcl/opengl/maskedTextureVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
new file mode 100644
index 000000000000..564426ce73d1
--- /dev/null
+++ b/vcl/opengl/salbmp.cxx
@@ -0,0 +1,513 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include "vcl/bitmap.hxx"
+#include "vcl/salbtype.hxx"
+#include "salgdi.hxx"
+
+#include "opengl/salbmp.hxx"
+
+static bool isValidBitCount( sal_uInt16 nBitCount )
+{
+ return (nBitCount == 1) || (nBitCount == 4) || (nBitCount == 8) || (nBitCount == 16) || (nBitCount == 24) || (nBitCount == 32);
+}
+
+OpenGLSalBitmap::OpenGLSalBitmap()
+: mpContext(NULL)
+, mbDirtyTexture(true)
+, mnBits(0)
+, mnBytesPerRow(0)
+, mnWidth(0)
+, mnHeight(0)
+, mnBufWidth(0)
+, mnBufHeight(0)
+, mnTexProgram(0)
+, mnConvProgram(0)
+{
+}
+
+OpenGLSalBitmap::~OpenGLSalBitmap()
+{
+ Destroy();
+ SAL_INFO( "vcl.opengl", "~OpenGLSalBitmap" );
+}
+
+bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight )
+{
+ static const BitmapPalette aEmptyPalette;
+
+ Destroy();
+ SAL_INFO( "vcl.opengl", "OpenGLSalBitmap::Create from FBO" );
+
+ mpContext = &rContext;
+ mpContext->makeCurrent();
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ mnBufWidth = 0;
+ mnBufHeight = 0;
+
+ // TODO Check the framebuffer configuration
+ mnBits = 32;
+ maPalette = aEmptyPalette;
+
+ mpTexture.reset( new OpenGLTexture( nX, nY, nWidth, nHeight ) );
+ mbDirtyTexture = false;
+
+ return true;
+}
+
+bool OpenGLSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
+{
+ Destroy();
+ SAL_INFO( "vcl.opengl", "OpenGLSalBitmap::Create with size" );
+
+ if( !isValidBitCount( nBits ) )
+ return false;
+ maPalette = rBitmapPalette;
+ mnBits = nBits;
+ mnWidth = mnBufWidth = rSize.Width();
+ mnHeight = mnBufHeight = rSize.Height();
+ return false;
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp )
+{
+ return Create( rSalBmp, rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ return Create( rSalBmp, pGraphics ? pGraphics->GetBitCount() : rSalBmp.GetBitCount() );
+}
+
+bool OpenGLSalBitmap::Create( const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount )
+{
+ const OpenGLSalBitmap& rSourceBitmap = static_cast<const OpenGLSalBitmap&>(rSalBmp);
+
+ SAL_INFO( "vcl.opengl", "OpenGLSalBitmap::Create from BMP " << rSourceBitmap.mnHeight );
+
+ if( isValidBitCount( nNewBitCount ) )
+ {
+ // TODO: lfrb: What about the pending operations?!
+ mnBits = nNewBitCount;
+ mnBytesPerRow = rSourceBitmap.mnBytesPerRow;
+ mnWidth = rSourceBitmap.mnWidth;
+ mnHeight = rSourceBitmap.mnHeight;
+ mnBufWidth = rSourceBitmap.mnBufWidth;
+ mnBufHeight = rSourceBitmap.mnBufHeight;
+ maPalette = rSourceBitmap.maPalette;
+ mpContext = rSourceBitmap.mpContext;
+ mpTexture = rSourceBitmap.mpTexture;
+ mbDirtyTexture = false;
+ maUserBuffer = rSourceBitmap.maUserBuffer;
+
+ // TODO Copy buffer data if the bitcount and palette are the same
+ return true;
+ }
+ return false;
+}
+
+bool OpenGLSalBitmap::Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
+{
+ // TODO Is this method needed?
+ return false;
+}
+
+bool OpenGLSalBitmap::Draw( OpenGLContext& rContext, const SalTwoRect& /*rPosAry*/ )
+{
+ if( !mpContext )
+ mpContext = &rContext;
+
+ if( !mpTexture || mbDirtyTexture )
+ {
+ if( !CreateTexture() )
+ return false;
+ }
+
+ //DrawTexture( mnTexture, rPosAry );
+ return true;
+}
+
+GLuint OpenGLSalBitmap::GetTexture( OpenGLContext& rContext ) const
+{
+ if( !mpContext )
+ const_cast<OpenGLSalBitmap*>(this)->mpContext = &rContext;
+ if( !mpTexture || mbDirtyTexture )
+ const_cast<OpenGLSalBitmap*>(this)->CreateTexture();
+ return mpTexture->Id();
+}
+
+void OpenGLSalBitmap::Destroy()
+{
+ SAL_INFO( "vcl.opengl", "Destroy OpenGLSalBitmap" );
+ maPendingOps.clear();
+ mpTexture.reset();
+ maUserBuffer.reset();
+}
+
+bool OpenGLSalBitmap::AllocateUserData()
+{
+ SAL_INFO( "vcl.opengl", "OpenGLSalBitmap::AllocateUserData" );
+
+ if( mnWidth && mnHeight )
+ {
+ mnBytesPerRow = 0;
+
+ switch( mnBits )
+ {
+ case 1: mnBytesPerRow = (mnWidth + 7) >> 3; break;
+ case 4: mnBytesPerRow = (mnWidth + 1) >> 1; break;
+ case 8: mnBytesPerRow = mnWidth; break;
+ case 16: mnBytesPerRow = mnWidth << 1; break;
+ case 24: mnBytesPerRow = (mnWidth << 1) + mnWidth; break;
+ case 32: mnBytesPerRow = mnWidth << 2; break;
+ default:
+ OSL_FAIL("vcl::OpenGLSalBitmap::AllocateUserData(), illegal bitcount!");
+ }
+ }
+
+ bool alloc = false;
+ if (mnBytesPerRow != 0
+ && mnBytesPerRow <= std::numeric_limits<sal_uInt32>::max() / mnHeight)
+ {
+ try
+ {
+ maUserBuffer.reset( new sal_uInt8[mnBytesPerRow * mnHeight] );
+ alloc = true;
+ }
+ catch (std::bad_alloc &) {}
+ }
+ if (!alloc)
+ {
+ SAL_WARN(
+ "vcl.opengl", "bad alloc " << mnBytesPerRow << "x" << mnHeight);
+ maUserBuffer.reset( static_cast<sal_uInt8*>(NULL) );
+ mnBytesPerRow = 0;
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ for (size_t i = 0; i < size_t(mnBytesPerRow * mnHeight); i++)
+ maUserBuffer.get()[i] = (i & 0xFF);
+ }
+#endif
+
+ return maUserBuffer.get() != 0;
+}
+
+class ImplPixelFormat
+{
+protected:
+ sal_uInt8* mpData;
+public:
+ static ImplPixelFormat* GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette );
+
+ virtual void StartLine( sal_uInt8* pLine ) { mpData = pLine; }
+ virtual const BitmapColor& ReadPixel() = 0;
+ virtual ~ImplPixelFormat() { }
+};
+
+class ImplPixelFormat8 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+
+public:
+ ImplPixelFormat8( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ return mrPalette[ *mpData++ ];
+ }
+};
+
+class ImplPixelFormat4 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+ sal_uInt32 mnShift;
+
+public:
+ ImplPixelFormat4( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+ {
+ mpData = pLine;
+ mnX = 0;
+ mnShift = 4;
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ const BitmapColor& rColor = mrPalette[( mpData[mnX >> 1] >> mnShift) & 0x0f];
+ mnX++;
+ mnShift ^= 4;
+ return rColor;
+ }
+};
+
+class ImplPixelFormat1 : public ImplPixelFormat
+{
+private:
+ const BitmapPalette& mrPalette;
+ sal_uInt32 mnX;
+
+public:
+ ImplPixelFormat1( const BitmapPalette& rPalette )
+ : mrPalette( rPalette )
+ {
+ }
+ virtual void StartLine( sal_uInt8* pLine ) SAL_OVERRIDE
+ {
+ mpData = pLine;
+ mnX = 0;
+ }
+ virtual const BitmapColor& ReadPixel() SAL_OVERRIDE
+ {
+ const BitmapColor& rColor = mrPalette[ (mpData[mnX >> 3 ] >> ( 7 - ( mnX & 7 ) )) & 1];
+ mnX++;
+ return rColor;
+ }
+};
+
+ImplPixelFormat* ImplPixelFormat::GetFormat( sal_uInt16 nBits, const BitmapPalette& rPalette )
+{
+ switch( nBits )
+ {
+ case 1: return new ImplPixelFormat1( rPalette );
+ case 4: return new ImplPixelFormat4( rPalette );
+ case 8: return new ImplPixelFormat8( rPalette );
+ }
+
+ return 0;
+}
+
+Size OpenGLSalBitmap::GetSize() const
+{
+ std::deque< OpenGLSalBitmapOp* >::const_iterator it = maPendingOps.begin();
+ Size aSize( mnWidth, mnHeight );
+
+ while( it != maPendingOps.end() )
+ (*it++)->GetSize( aSize );
+
+ return aSize;
+}
+
+GLuint OpenGLSalBitmap::CreateTexture()
+{
+ GLenum nFormat, nType;
+ sal_uInt8* pData( NULL );
+ bool bAllocated( false );
+
+ if( maUserBuffer.get() != 0 )
+ {
+ if( mnBits == 16 || mnBits == 24 || mnBits == 32 )
+ {
+ // no conversion needed for truecolor
+ pData = maUserBuffer.get();
+
+ switch( mnBits )
+ {
+ case 16: nFormat = GL_RGB;
+ nType = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case 24: nFormat = GL_RGB;
+ nType = GL_UNSIGNED_BYTE;
+ break;
+ case 32: nFormat = GL_RGBA;
+ nType = GL_UNSIGNED_BYTE;
+ break;
+ }
+ }
+ else if( mnBits == 8 && maPalette.IsGreyPalette() )
+ {
+ // no conversion needed for grayscale
+ pData = maUserBuffer.get();
+ nFormat = GL_LUMINANCE;
+ nType = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ // convert to 32 bits RGBA using palette
+ pData = new sal_uInt8[ mnBufHeight * (mnBufWidth << 2) ];
+ bAllocated = true;
+ nFormat = GL_RGBA;
+ nType = GL_UNSIGNED_BYTE;
+
+ ImplPixelFormat* pSrcFormat = ImplPixelFormat::GetFormat( mnBits, maPalette );
+ sal_uInt8* pSrcData = maUserBuffer.get();
+ sal_uInt8* pDstData = pData;
+
+ sal_uInt32 nY = mnBufHeight;
+ while( nY-- )
+ {
+ pSrcFormat->StartLine( pSrcData );
+
+ sal_uInt32 nX = mnBufWidth;
+ while( nX-- )
+ {
+ const BitmapColor& c = pSrcFormat->ReadPixel();
+
+ *pDstData++ = c.GetRed();
+ *pDstData++ = c.GetGreen();
+ *pDstData++ = c.GetBlue();
+ *pDstData++ = 255;
+ }
+
+ pSrcData += mnBytesPerRow;
+ }
+ }
+ }
+
+ SAL_INFO( "vcl.opengl", "::CreateTexture" );
+ mpContext->makeCurrent();
+ mpTexture.reset( new OpenGLTexture (mnBufWidth, mnBufHeight, nFormat, nType, pData ) );
+
+ if( bAllocated )
+ delete pData;
+
+ while( !maPendingOps.empty() )
+ {
+ OpenGLSalBitmapOp* pOp = maPendingOps.front();
+ pOp->Execute();
+ maPendingOps.pop_front();
+ }
+
+ mbDirtyTexture = false;
+ return mpTexture->Id();
+}
+
+bool OpenGLSalBitmap::ReadTexture()
+{
+ SalTwoRect aPosAry;
+ GLuint nFramebufferId, nRenderbufferDepthId, nRenderbufferColorId;
+ sal_uInt8* pData = maUserBuffer.get();
+
+ // TODO Check mnTexWidth and mnTexHeight
+
+ mpContext->makeCurrent();
+ OpenGLHelper::createFramebuffer( mnWidth, mnHeight, nFramebufferId,
+ nRenderbufferDepthId, nRenderbufferColorId, true );
+ glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
+
+ aPosAry.mnSrcX = aPosAry.mnDestX = 0;
+ aPosAry.mnSrcY = aPosAry.mnDestY = 0;
+ aPosAry.mnSrcWidth = aPosAry.mnDestWidth = mnWidth;
+ aPosAry.mnSrcHeight = aPosAry.mnDestHeight = mnHeight;
+
+ //DrawTexture( mnTexture, aPosAry );
+ glReadPixels( 0, 0, mnWidth, mnHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData );
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glDeleteFramebuffers( 1, &nFramebufferId );
+ glDeleteRenderbuffers( 1, &nRenderbufferDepthId );
+ glDeleteRenderbuffers( 1, &nRenderbufferColorId );
+
+ return true;
+}
+
+sal_uInt16 OpenGLSalBitmap::GetBitCount() const
+{
+ return mnBits;
+}
+
+BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
+{
+ if( !maUserBuffer.get() )
+ {
+ if( !AllocateUserData() )
+ return NULL;
+ if( mpTexture && !ReadTexture() )
+ return NULL;
+ }
+
+ BitmapBuffer* pBuffer = new BitmapBuffer;
+ pBuffer->mnWidth = mnWidth;
+ pBuffer->mnHeight = mnHeight;
+ pBuffer->maPalette = maPalette;
+ pBuffer->mnScanlineSize = mnBytesPerRow;
+ pBuffer->mpBits = maUserBuffer.get();
+ pBuffer->mnBitCount = mnBits;
+ switch( mnBits )
+ {
+ case 1: pBuffer->mnFormat = BMP_FORMAT_1BIT_MSB_PAL; break;
+ case 4: pBuffer->mnFormat = BMP_FORMAT_4BIT_MSN_PAL; break;
+ case 8: pBuffer->mnFormat = BMP_FORMAT_8BIT_PAL; break;
+ case 16: pBuffer->mnFormat = BMP_FORMAT_16BIT_TC_MSB_MASK;
+ pBuffer->maColorMask = ColorMask( 0xf800, 0x07e0, 0x001f );
+ break;
+ case 24: pBuffer->mnFormat = BMP_FORMAT_24BIT_TC_RGB; break;
+ case 32: pBuffer->mnFormat = BMP_FORMAT_32BIT_TC_RGBA;
+ pBuffer->maColorMask = ColorMask( 0xff000000, 0x00ff0000, 0x0000ff00 );
+ break;
+ }
+
+ return pBuffer;
+}
+
+void OpenGLSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
+{
+ if( !bReadOnly )
+ {
+ mbDirtyTexture = true;
+ }
+ delete pBuffer;
+}
+
+bool OpenGLSalBitmap::GetSystemData( BitmapSystemData& /*rData*/ )
+{
+#if 0
+ // TODO Implement for ANDROID/OSX/IOS/WIN32
+ X11SalBitmap rBitmap;
+ BitmapBuffer* pBuffer;
+
+ rBitmap.Create( GetSize(), mnBits, maPalette );
+ pBuffer = rBitmap.AcquireBuffer( false );
+ if( pBuffer == NULL )
+ return false;
+
+ if( !maUserBuffer.get() )
+ {
+ if( !AllocateUserData() || !ReadTexture() )
+ {
+ rBitmap.ReleaseBuffer( pBuffer, false );
+ return false;
+ }
+ }
+
+ // TODO Might be more efficient to add a static method to SalBitmap
+ // to get system data from a buffer
+ memcpy( pBuffer->mpBits, maUserBuffer.get(), mnBytesPerRow * mnHeight );
+
+ rBitmap.ReleaseBuffer( pBuffer, false );
+ return rBitmap.GetSystemData( rData );
+#else
+ return false;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
new file mode 100644
index 000000000000..16710b41bdd1
--- /dev/null
+++ b/vcl/opengl/scale.cxx
@@ -0,0 +1,308 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include "vcl/bitmap.hxx"
+
+#include "opengl/bmpop.hxx"
+#include "opengl/salbmp.hxx"
+#include "opengl/texture.hxx"
+
+class ScaleOp : public OpenGLSalBitmapOp
+{
+private:
+ OpenGLSalBitmap* mpBitmap;
+ double mfScaleX;
+ double mfScaleY;
+ sal_uInt32 mnScaleFlag;
+
+public:
+ ScaleOp( OpenGLSalBitmap* pBitmap, const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag );
+
+ bool Execute() SAL_OVERRIDE;
+ void GetSize( Size& rSize ) const SAL_OVERRIDE;
+};
+
+
+GLuint OpenGLSalBitmap::ImplGetTextureProgram()
+{
+ if( mnTexProgram == 0 )
+ {
+ mnTexProgram = OpenGLHelper::LoadShaders( "textureVertexShader",
+ "textureFragmentShader" );
+ if( mnTexProgram == 0 )
+ return 0;
+
+ glBindAttribLocation( mnTexProgram, 0, "position" );
+ glBindAttribLocation( mnTexProgram, 1, "tex_coord_in" );
+ mnTexSamplerUniform = glGetUniformLocation( mnTexProgram, "sampler" );
+ }
+
+ return mnTexProgram;
+}
+
+GLuint OpenGLSalBitmap::ImplGetConvolutionProgram()
+{
+ if( mnConvProgram == 0 )
+ {
+ mnConvProgram = OpenGLHelper::LoadShaders( "textureVertexShader",
+ "convolutionFragmentShader" );
+ if( mnConvProgram == 0 )
+ return 0;
+
+ glBindAttribLocation( mnConvProgram, 0, "position" );
+ glBindAttribLocation( mnConvProgram, 1, "tex_coord_in" );
+ mnConvSamplerUniform = glGetUniformLocation( mnConvProgram, "sampler" );
+ mnConvKernelUniform = glGetUniformLocation( mnConvProgram, "kernel" );
+ mnConvOffsetsUniform = glGetUniformLocation( mnConvProgram, "offsets" );
+ }
+
+ return mnConvProgram;
+}
+
+bool OpenGLSalBitmap::ImplScaleFilter( GLenum nFilter )
+{
+ OpenGLTexture* pNewTex;
+ GLuint nProgram;
+ GLuint nFramebufferId;
+ GLenum nOldFilter;
+
+ nProgram = ImplGetTextureProgram();
+ if( nProgram == 0 )
+ return false;
+
+ glGenFramebuffers( 1, &nFramebufferId );
+ glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
+ glUseProgram( nProgram );
+ glUniform1i( mnTexSamplerUniform, 0 );
+
+ pNewTex = new OpenGLTexture( mnWidth, mnHeight );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pNewTex->Id(), 0 );
+
+ mpTexture->Bind();
+ nOldFilter = mpTexture->GetFilter();
+ mpTexture->SetFilter( nFilter );
+ mpTexture->Draw();
+ mpTexture->SetFilter( nOldFilter );
+ mpTexture->Unbind();
+
+ glUseProgram( 0 );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glDeleteFramebuffers( 1, &nFramebufferId );
+
+ mpTexture.reset( pNewTex );
+ return true;
+}
+
+void OpenGLSalBitmap::ImplCreateKernel(
+ const double& fScale,
+ const Kernel& rKernel,
+ GLfloat*& pWeights,
+ sal_uInt32& aKernelSize )
+{
+ const double fSamplingRadius(rKernel.GetWidth());
+ const double fScaledRadius((fScale < 1.0) ? fSamplingRadius / fScale : fSamplingRadius);
+ const double fFilterFactor((fScale < 1.0) ? fScale : 1.0);
+ int aNumberOfContributions;
+ double aSum( 0 );
+
+ aNumberOfContributions = (static_cast< sal_uInt32 >(fabs(ceil(fScaledRadius))) * 2) + 1 - 6;
+ aKernelSize = aNumberOfContributions / 2 + 1;
+
+ pWeights = new GLfloat[16];
+ memset( pWeights, 0, 16 * sizeof( GLfloat ) );
+
+ for( sal_uInt32 i(0); i < aKernelSize; i++ )
+ {
+ const GLfloat aWeight( rKernel.Calculate( fFilterFactor * i ) );
+ if( fabs( aWeight ) >= 0.0001 )
+ {
+ pWeights[i] = aWeight;
+ aSum += i > 0 ? aWeight * 2 : aWeight;
+ }
+ }
+
+ for( sal_uInt32 i(0); i < aKernelSize; i++ )
+ {
+ pWeights[i] /= aSum;
+ }
+}
+
+bool OpenGLSalBitmap::ImplScaleConvolution(
+ const double& rScaleX,
+ const double& rScaleY,
+ const Kernel& aKernel )
+{
+ OpenGLTexture* pScratchTex;
+ OpenGLTexture* pNewTex;
+ GLfloat* pWeights( 0 );
+ GLuint nFramebufferId;
+ GLuint nProgram;
+ sal_uInt32 nKernelSize;
+ GLfloat aOffsets[32];
+ int nNewWidth( mnWidth * rScaleX );
+ int nNewHeight( mnHeight * rScaleY );
+
+ // TODO Make sure the framebuffer is alright
+
+ nProgram = ImplGetConvolutionProgram();
+ if( nProgram == 0 )
+ return false;
+
+ glGenFramebuffers( 1, &nFramebufferId );
+ glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
+ glUseProgram( nProgram );
+ glUniform1i( mnConvSamplerUniform, 0 );
+ CHECK_GL_ERROR();
+
+ // horizontal scaling in scratch texture
+ pScratchTex = new OpenGLTexture( nNewWidth, mnHeight );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pScratchTex->Id(), 0 );
+ CHECK_GL_ERROR();
+
+ for( sal_uInt32 i = 0; i < 16; i++ )
+ {
+ aOffsets[i * 2] = i / (double) mnWidth;
+ aOffsets[i * 2 + 1] = 0;
+ }
+ ImplCreateKernel( rScaleX, aKernel, pWeights, nKernelSize );
+ glUniform1fv( mnConvKernelUniform, 16, pWeights );
+ CHECK_GL_ERROR();
+ glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
+ CHECK_GL_ERROR();
+
+ glViewport( 0, 0, nNewWidth, mnHeight );
+ mpTexture->Bind();
+ mpTexture->Draw();
+ mpTexture->Unbind();
+
+ // vertical scaling in final texture
+ pNewTex = new OpenGLTexture( nNewWidth, nNewHeight );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pNewTex->Id(), 0 );
+
+ for( sal_uInt32 i = 0; i < 16; i++ )
+ {
+ aOffsets[i * 2] = 0;
+ aOffsets[i * 2 + 1] = i / (double) mnHeight;
+ }
+ ImplCreateKernel( rScaleY, aKernel, pWeights, nKernelSize );
+ glUniform1fv( mnConvKernelUniform, 16, pWeights );
+ glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
+ CHECK_GL_ERROR();
+
+ glViewport( 0, 0, nNewWidth, nNewHeight );
+ pScratchTex->Bind();
+ pScratchTex->Draw();
+ pScratchTex->Unbind();
+
+ glUseProgram( 0 );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glDeleteFramebuffers( 1, &nFramebufferId );
+
+ delete pScratchTex;
+ mpTexture.reset( pNewTex );
+ mnWidth = nNewWidth;
+ mnHeight = nNewHeight;
+
+ return true;
+}
+
+bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
+{
+ SAL_INFO( "vcl.opengl", "::ImplScale" );
+
+ if( nScaleFlag == BMP_SCALE_FAST )
+ {
+ return ImplScaleFilter( GL_NEAREST );
+ }
+ if( nScaleFlag == BMP_SCALE_BILINEAR )
+ {
+ return ImplScaleFilter( GL_LINEAR );
+ }
+ else if( nScaleFlag == BMP_SCALE_SUPER )
+ {
+ const Lanczos3Kernel aKernel;
+
+ return ImplScaleConvolution( rScaleX, rScaleY, aKernel );
+ }
+ else if( nScaleFlag == BMP_SCALE_LANCZOS )
+ {
+ const Lanczos3Kernel aKernel;
+
+ return ImplScaleConvolution( rScaleX, rScaleY, aKernel );
+ }
+
+ SAL_WARN( "vcl.opengl", "Invalid flag for scaling operation" );
+ return false;
+}
+
+ScaleOp::ScaleOp(
+ OpenGLSalBitmap* pBitmap,
+ const double& rScaleX,
+ const double& rScaleY,
+ sal_uInt32 nScaleFlag )
+: mpBitmap( pBitmap )
+, mfScaleX( rScaleX )
+, mfScaleY( rScaleY )
+, mnScaleFlag( nScaleFlag )
+{
+}
+
+bool ScaleOp::Execute()
+{
+ SAL_INFO( "vcl.opengl", "::Execute" );
+ return mpBitmap->ImplScale( mfScaleX, mfScaleY, mnScaleFlag );
+}
+
+void ScaleOp::GetSize( Size& rSize ) const
+{
+ SAL_INFO( "vcl.opengl", "::GetSize" );
+ rSize.setWidth( rSize.Width() * mfScaleX );
+ rSize.setHeight( rSize.Height() * mfScaleY );
+}
+
+bool OpenGLSalBitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
+{
+ SAL_INFO( "vcl.opengl", "::Scale " << nScaleFlag );
+
+ if( nScaleFlag == BMP_SCALE_FAST ||
+ nScaleFlag == BMP_SCALE_BILINEAR ||
+ nScaleFlag == BMP_SCALE_SUPER ||
+ nScaleFlag == BMP_SCALE_LANCZOS )
+ {
+ //TODO maUserBuffer.reset();
+ if( mpContext == NULL )
+ {
+ SAL_INFO( "vcl.opengl", "Add ScaleOp to pending operations" );
+ maPendingOps.push_back( new ScaleOp( this, rScaleX, rScaleY, nScaleFlag ) );
+ }
+ else
+ {
+ ImplScale( rScaleX, rScaleY, nScaleFlag );
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/solidFragmentShader.glsl b/vcl/opengl/solidFragmentShader.glsl
new file mode 100644
index 000000000000..af7533604cef
--- /dev/null
+++ b/vcl/opengl/solidFragmentShader.glsl
@@ -0,0 +1,17 @@
+/* -*- 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/.
+ */
+
+/*precision mediump float;*/
+
+uniform vec4 color;
+void main() {
+ gl_FragColor = color;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/solidVertexShader.glsl
new file mode 100644
index 000000000000..47061f6e4223
--- /dev/null
+++ b/vcl/opengl/solidVertexShader.glsl
@@ -0,0 +1,16 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+void main() {
+ gl_Position = position;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
new file mode 100644
index 000000000000..2770c20a5519
--- /dev/null
+++ b/vcl/opengl/texture.cxx
@@ -0,0 +1,144 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include "vcl/salbtype.hxx"
+
+#include "opengl/texture.hxx"
+
+OpenGLTexture::OpenGLTexture()
+: mnTexture( 0 )
+, mnWidth( -1 )
+, mnHeight( -1 )
+, mnFilter( GL_NEAREST )
+{
+}
+
+OpenGLTexture::OpenGLTexture( int nWidth, int nHeight )
+: mnTexture( 0 )
+, mnWidth( nWidth )
+, mnHeight( nHeight )
+, mnFilter( GL_NEAREST )
+{
+ glGenTextures( 1, &mnTexture );
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+}
+
+OpenGLTexture::OpenGLTexture( int nX, int nY, int nWidth, int nHeight )
+: mnTexture( 0 )
+, mnWidth( nWidth )
+, mnHeight( nHeight )
+, mnFilter( GL_NEAREST )
+{
+ glGenTextures( 1, &mnTexture );
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nX, nY, nWidth, nHeight, 0 );
+ CHECK_GL_ERROR();
+ glBindTexture( GL_TEXTURE_2D, 0 );
+ CHECK_GL_ERROR();
+}
+
+OpenGLTexture::OpenGLTexture( int nWidth, int nHeight, int nFormat, int nType, sal_uInt8* pData )
+: mnTexture( 0 )
+, mnWidth( nWidth )
+, mnHeight( nHeight )
+, mnFilter( GL_NEAREST )
+{
+ if( !mnTexture )
+ glGenTextures( 1, &mnTexture );
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, mnWidth, mnHeight, 0, nFormat, nType, pData );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+}
+
+OpenGLTexture::~OpenGLTexture()
+{
+ if( mnTexture != 0 )
+ glDeleteTextures( 1, &mnTexture );
+}
+
+GLuint OpenGLTexture::Id() const
+{
+ return mnTexture;
+}
+
+GLenum OpenGLTexture::GetFilter() const
+{
+ return mnFilter;
+}
+
+void OpenGLTexture::SetFilter( GLenum nFilter )
+{
+ mnFilter = nFilter;
+ if( mnTexture )
+ {
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, nFilter );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, nFilter );
+ }
+}
+
+void OpenGLTexture::Bind()
+{
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+}
+
+void OpenGLTexture::Unbind()
+{
+ glBindTexture( GL_TEXTURE_2D, 0 );
+}
+
+bool OpenGLTexture::Draw()
+{
+ const GLfloat aPosition[8] = { -1, -1, -1, 1, 1, 1, 1, -1 };
+ const GLfloat aTexCoord[8] = { 0, 0, 0, 1, 1, 1, 1, 0 };
+
+ if( mnTexture == 0 )
+ return false;
+
+ glBindTexture( GL_TEXTURE_2D, mnTexture );
+ glEnableVertexAttribArray( 0 );
+ glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, aPosition );
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ glDisableVertexAttribArray( 0 );
+ glDisableVertexAttribArray( 1 );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/textureFragmentShader.glsl b/vcl/opengl/textureFragmentShader.glsl
new file mode 100644
index 000000000000..cc95f2ffb17c
--- /dev/null
+++ b/vcl/opengl/textureFragmentShader.glsl
@@ -0,0 +1,18 @@
+/* -*- 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/.
+ */
+
+/* precision mediump float; */
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+
+void main() {
+ gl_FragColor = texture2D(sampler, tex_coord);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/textureVertexShader.glsl b/vcl/opengl/textureVertexShader.glsl
new file mode 100644
index 000000000000..99d7f37eb05f
--- /dev/null
+++ b/vcl/opengl/textureVertexShader.glsl
@@ -0,0 +1,19 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+varying vec2 tex_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
new file mode 100644
index 000000000000..e829ca445f42
--- /dev/null
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -0,0 +1,65 @@
+/* -*- 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/.
+ */
+
+#include "opengl/win/gdiimpl.hxx"
+
+#include <win/wincomp.hxx>
+#include <win/saldata.hxx>
+#include <win/salframe.h>
+
+WinOpenGLSalGraphicsImpl::WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics):
+ mrParent(rGraphics)
+{
+}
+
+GLfloat WinOpenGLSalGraphicsImpl::GetWidth() const
+{
+ if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) )
+ {
+ WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() );
+ if( pFrame )
+ {
+ if( pFrame->maGeometry.nWidth )
+ return pFrame->maGeometry.nWidth;
+ else
+ {
+ // TODO: perhaps not needed, maGeometry should always be up-to-date
+ RECT aRect;
+ GetClientRect( mrParent.gethWnd(), &aRect );
+ return aRect.right;
+ }
+ }
+ }
+
+ return 1;
+}
+
+GLfloat WinOpenGLSalGraphicsImpl::GetHeight() const
+{
+ if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) )
+ {
+ WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() );
+ if( pFrame )
+ {
+ if( pFrame->maGeometry.nHeight )
+ return pFrame->maGeometry.nHeight;
+ else
+ {
+ // TODO: perhaps not needed, maGeometry should always be up-to-date
+ RECT aRect;
+ GetClientRect( mrParent.gethWnd(), &aRect );
+ return aRect.bottom;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
new file mode 100644
index 000000000000..11735edb271c
--- /dev/null
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -0,0 +1,139 @@
+/* -*- 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/.
+ */
+
+#include "vcl/salbtype.hxx"
+
+#include "unx/pixmap.hxx"
+#include "unx/saldisp.hxx"
+#include "unx/salframe.h"
+#include "unx/salgdi.h"
+#include "unx/salvd.h"
+
+#include "opengl/x11/gdiimpl.hxx"
+
+#include <vcl/opengl/OpenGLContext.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ):
+ OpenGLSalGraphicsImpl(),
+ mrParent(rParent)
+{
+}
+
+X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl()
+{
+}
+
+GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nWidth;
+ else if( mrParent.m_pVDev )
+ {
+ long nWidth = 0;
+ long nHeight = 0;
+ mrParent.m_pVDev->GetSize( nWidth, nHeight );
+ return nWidth;
+ }
+ return 1;
+}
+
+GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nHeight;
+ else if( mrParent.m_pVDev )
+ {
+ long nWidth = 0;
+ long nHeight = 0;
+ mrParent.m_pVDev->GetSize( nWidth, nHeight );
+ return nHeight;
+ }
+ return 1;
+}
+
+void X11OpenGLSalGraphicsImpl::Init()
+{
+ if( mrParent.m_pFrame && dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame) )
+ {
+ Window aWin = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame)->GetX11Window();
+ maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen());
+ }
+ else if( mrParent.m_pVDev )
+ {
+ maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
+ mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
+ mrParent.m_nXScreen.getXScreen() );
+ }
+ else
+ {
+ SAL_WARN( "vcl.opengl", "what happened here?" );
+ }
+}
+
+X11Pixmap* X11OpenGLSalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect )
+{
+ Display* pDisplay = mrParent.GetXDisplay();
+ SalX11Screen nScreen = mrParent.GetScreenNumber();
+
+ SAL_INFO( "vcl.opengl", "GetPixmapFromScreen" );
+ return new X11Pixmap( pDisplay, nScreen, rRect.GetWidth(), rRect.GetHeight(), 24 );
+}
+
+bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
+{
+ const int aAttribs[] = {
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ None
+ };
+ Display* pDisplay = mrParent.GetXDisplay();
+ GLXFBConfig pFbConfig;
+ GLXPixmap pGlxPixmap;
+ GLuint nTexture;
+ SalTwoRect aPosAry;
+ bool bInverted;
+
+ SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" );
+
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ aPosAry.mnDestX = nX;
+ aPosAry.mnDestY = nY;
+ aPosAry.mnSrcWidth = aPosAry.mnDestWidth = pPixmap->GetWidth();
+ aPosAry.mnSrcHeight = aPosAry.mnDestHeight = pPixmap->GetHeight();
+
+ XSync( pDisplay, 0 );
+ pFbConfig = OpenGLHelper::GetPixmapFBConfig( pDisplay, bInverted );
+ pGlxPixmap = glXCreatePixmap( pDisplay, pFbConfig, pPixmap->GetPixmap(), aAttribs);
+ XSync( pDisplay, 0 );
+
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
+
+ glGenTextures( 1, &nTexture );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, nTexture );
+
+ //TODO: lfrb: glXGetProc to get the functions
+ glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ DrawTexture( nTexture, pPixmap->GetSize(), aPosAry );
+
+ glXReleaseTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT );
+ glDeleteTextures( 1, &nTexture );
+ glXDestroyPixmap( pDisplay, pGlxPixmap );
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx
index a9805100d907..c4cf2b00a011 100644
--- a/vcl/quartz/salbmp.cxx
+++ b/vcl/quartz/salbmp.cxx
@@ -963,4 +963,9 @@ bool QuartzSalBitmap::GetSystemData( BitmapSystemData& rData )
return bRet;
}
+bool QuartzSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, sal_uInt32 /*nScaleFlag*/ )
+{
+ return false;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx
index 5f6477a00b82..ccd914d5b924 100644
--- a/vcl/source/gdi/bitmap.cxx
+++ b/vcl/source/gdi/bitmap.cxx
@@ -60,8 +60,7 @@ Bitmap::Bitmap( const Bitmap& rBitmap ) :
Bitmap::Bitmap( SalBitmap* pSalBitmap )
{
- mpImpBmp = new ImpBitmap();
- mpImpBmp->ImplSetSalBitmap( pSalBitmap );
+ mpImpBmp = new ImpBitmap(pSalBitmap);
maPrefMapMode = MapMode( MAP_PIXEL );
maPrefSize = mpImpBmp->ImplGetSize();
}
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 588dd0a2d50c..335d625b29ab 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -27,6 +27,7 @@
#include <boost/scoped_array.hpp>
+#include <impbmp.hxx>
#include <impoct.hxx>
#include <impvect.hxx>
@@ -873,6 +874,25 @@ bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nSc
bRetval = true;
}
+ if( mpImpBmp )
+ {
+ // implementation specific scaling
+ ImpBitmap* pImpBmp = new ImpBitmap;
+
+ if( pImpBmp->ImplCreate( *mpImpBmp ) && pImpBmp->ImplScale( rScaleX, rScaleY, nScaleFlag ) )
+ {
+ ImplSetImpBitmap( pImpBmp );
+ SAL_INFO( "vcl.opengl", "Ref count: " << mpImpBmp->ImplGetRefCount() );
+ maPrefMapMode = MapMode( MAP_PIXEL );
+ maPrefSize = pImpBmp->ImplGetSize();
+ return true;
+ }
+ else
+ {
+ delete pImpBmp;
+ }
+ }
+
//fdo#33455
//
//If we start with a 1 bit image, then after scaling it in any mode except
diff --git a/vcl/source/gdi/impbmp.cxx b/vcl/source/gdi/impbmp.cxx
index 005a45e6e9aa..633cff2a5c64 100644
--- a/vcl/source/gdi/impbmp.cxx
+++ b/vcl/source/gdi/impbmp.cxx
@@ -31,6 +31,13 @@ ImpBitmap::ImpBitmap() :
{
}
+ImpBitmap::ImpBitmap(SalBitmap* pBitmap) :
+ mnRefCount ( 1 ),
+ mnChecksum ( 0 ),
+ mpSalBitmap ( pBitmap )
+{
+}
+
ImpBitmap::~ImpBitmap()
{
delete mpSalBitmap;
@@ -86,4 +93,9 @@ void ImpBitmap::ImplReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
mnChecksum = 0;
}
+bool ImpBitmap::ImplScale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
+{
+ return mpSalBitmap->Scale( rScaleX, rScaleY, nScaleFlag );
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/salgdiimpl.cxx b/vcl/source/gdi/salgdiimpl.cxx
new file mode 100644
index 000000000000..96ba3828996b
--- /dev/null
+++ b/vcl/source/gdi/salgdiimpl.cxx
@@ -0,0 +1,26 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "salgdiimpl.hxx"
+
+SalGraphicsImpl::~SalGraphicsImpl()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 79430ba5a78e..1062a879a09d 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -25,6 +25,10 @@
using namespace com::sun::star;
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+static std::vector< GLXContext > vShareList;
+#endif
+
GLWindow::~GLWindow()
{
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
@@ -36,8 +40,13 @@ OpenGLContext::OpenGLContext():
mpWindow(NULL),
m_pChildWindow(NULL),
mbInitialized(false),
- mbRequestLegacyContext(false)
+ mbRequestLegacyContext(false),
+ mbUseDoubleBufferedRendering(true),
+ mbRequestVirtualDevice(false)
{
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+ mbPixmap = false;
+#endif
}
OpenGLContext::~OpenGLContext()
@@ -56,12 +65,17 @@ OpenGLContext::~OpenGLContext()
#elif defined( UNX )
if(m_aGLWin.ctx)
{
+ std::remove( vShareList.begin(), vShareList.end(), m_aGLWin.ctx );
+
glXMakeCurrent(m_aGLWin.dpy, None, NULL);
if( glGetError() != GL_NO_ERROR )
{
SAL_WARN("vcl.opengl", "glError: " << (char *)gluErrorString(glGetError()));
}
glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx);
+
+ if (mbPixmap)
+ glXDestroyGLXPixmap(m_aGLWin.dpy, m_aGLWin.glPix);
}
#endif
}
@@ -71,6 +85,16 @@ void OpenGLContext::requestLegacyContext()
mbRequestLegacyContext = true;
}
+void OpenGLContext::requestSingleBufferedRendering()
+{
+ mbUseDoubleBufferedRendering = false;
+}
+
+void OpenGLContext::requestVirtualDevice()
+{
+ mbRequestVirtualDevice = true;
+}
+
#if defined( _WIN32 )
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -154,7 +178,7 @@ bool WGLisExtensionSupported(const char *extension)
supported = (char*)glGetString(GL_EXTENSIONS);
// If That Failed Too, Must Be No Extensions Supported
if (supported == NULL)
- return 0;
+ return false;
// Begin Examination At Start Of String, Increment By 1 On False Match
for (const char* p = supported; ; p++)
@@ -176,7 +200,8 @@ bool WGLisExtensionSupported(const char *extension)
}
}
-bool InitMultisample(PIXELFORMATDESCRIPTOR pfd, int& rPixelFormat)
+bool InitMultisample(PIXELFORMATDESCRIPTOR pfd, int& rPixelFormat,
+ bool bUseDoubleBufferedRendering, bool bRequestVirtualDevice)
{
HWND hWnd = NULL;
GLWindow glWin;
@@ -213,6 +238,7 @@ bool InitMultisample(PIXELFORMATDESCRIPTOR pfd, int& rPixelFormat)
// We Support Multisampling On This Hardware.
int iAttributes[] =
{
+ WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
@@ -220,12 +246,19 @@ bool InitMultisample(PIXELFORMATDESCRIPTOR pfd, int& rPixelFormat)
WGL_ALPHA_BITS_ARB,8,
WGL_DEPTH_BITS_ARB,24,
WGL_STENCIL_BITS_ARB,0,
- WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
WGL_SAMPLES_ARB,8,
0,0
};
+ if (!bUseDoubleBufferedRendering)
+ iAttributes[1] = GL_FALSE;
+
+ if (bRequestVirtualDevice)
+ {
+ iAttributes[2] = WGL_DRAW_TO_BITMAP_ARB;
+ }
+
bool bArbMultisampleSupported = true;
// First We Check To See If We Can Get A Pixel Format For 4 Samples
@@ -369,22 +402,69 @@ int oglErrorHandler( Display* /*dpy*/, XErrorEvent* /*evnt*/ )
return 0;
}
-GLXFBConfig* getFBConfig(const SystemEnvData* sysData, int& nBestFBC)
+GLXFBConfig* getFBConfigForPixmap(Display* dpy, int& nBestFBC, bool bUseDoubleBufferedRendering, int screen)
{
- Display *dpy = reinterpret_cast<Display*>(sysData->pDisplay);
+ static int visual_attribs[] =
+ {
+ GLX_DOUBLEBUFFER, False,
+ GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
+ GLX_X_RENDERABLE, True,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DEPTH_SIZE, 24,
+ GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
+ None
+ };
- if( dpy == 0 || !glXQueryExtension( dpy, NULL, NULL ) )
+ if (bUseDoubleBufferedRendering)
+ visual_attribs[1] = True;
+
+ int fbCount = 0;
+ GLXFBConfig* pFBC = glXChooseFBConfig( dpy,
+ screen,
+ visual_attribs, &fbCount );
+
+ if(!pFBC)
+ {
+ SAL_WARN("vcl.opengl", "no suitable fb format found");
return NULL;
+ }
- Window win = sysData->aWindow;
+ int best_num_samp = -1;
+ for(int i = 0; i < fbCount; ++i)
+ {
+ // pick the one with the most samples per pixel
+ int nSampleBuf = 0;
+ int nSamples = 0;
+ glXGetFBConfigAttrib( dpy, pFBC[i], GLX_SAMPLE_BUFFERS, &nSampleBuf );
+ glXGetFBConfigAttrib( dpy, pFBC[i], GLX_SAMPLES , &nSamples );
+
+ if ( nBestFBC < 0 || (nSampleBuf && ( nSamples > best_num_samp )) )
+ {
+ nBestFBC = i;
+ best_num_samp = nSamples;
+ }
+ }
- SAL_INFO("vcl.opengl", "parent window: " << win);
+ return pFBC;
+}
+
+#ifdef DBG_UTIL
+GLXFBConfig* getFBConfig(Display* dpy, Window win, int& nBestFBC, bool bUseDoubleBufferedRendering)
+{
+ if( dpy == 0 || !glXQueryExtension( dpy, NULL, NULL ) )
+ return NULL;
+
+ SAL_INFO("vcl.opengl", "window: " << win);
XWindowAttributes xattr;
XGetWindowAttributes( dpy, win, &xattr );
int screen = XScreenNumberOfScreen( xattr.screen );
+ // TODO: moggi: Select colour channel depth based on visual attributes, not hardcoded */
static int visual_attribs[] =
{
GLX_DOUBLEBUFFER, True,
@@ -397,6 +477,10 @@ GLXFBConfig* getFBConfig(const SystemEnvData* sysData, int& nBestFBC)
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
None
};
+
+ if (!bUseDoubleBufferedRendering)
+ visual_attribs[1] = False;
+
int fbCount = 0;
GLXFBConfig* pFBC = glXChooseFBConfig( dpy,
screen,
@@ -412,7 +496,7 @@ GLXFBConfig* getFBConfig(const SystemEnvData* sysData, int& nBestFBC)
for(int i = 0; i < fbCount; ++i)
{
XVisualInfo* pVi = glXGetVisualFromFBConfig( dpy, pFBC[i] );
- if(pVi)
+ if(pVi && pVi->visualid == xattr.visual->visualid)
{
// pick the one with the most samples per pixel
int nSampleBuf = 0;
@@ -431,6 +515,27 @@ GLXFBConfig* getFBConfig(const SystemEnvData* sysData, int& nBestFBC)
return pFBC;
}
+#endif
+
+// we need them before glew can initialize them
+// glew needs an OpenGL context so we need to get the address manually
+void initOpenGLFunctionPointers()
+{
+ glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
+ glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig"); // try to find a visual for the current set of attributes
+ glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
+ glXCreateContextAttribsARB = (GLXContext(*) (Display*, GLXFBConfig, GLXContext, Bool, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");;
+}
+
+Visual* getVisual(Display* dpy, Window win)
+{
+ initOpenGLFunctionPointers();
+
+ XWindowAttributes xattr;
+ XGetWindowAttributes( dpy, win, &xattr );
+ SAL_INFO("vcl.opengl", "using VisualID " << xattr.visual);
+ return xattr.visual;
+}
}
@@ -443,6 +548,8 @@ bool OpenGLContext::init( vcl::Window* pParent )
m_pWindow.reset(pParent ? NULL : new vcl::Window(0, WB_NOBORDER|WB_NODIALOGCONTROL));
mpWindow = pParent ? pParent : m_pWindow.get();
+ if(m_pWindow)
+ m_pWindow->setPosSizePixel(0,0,0,0);
m_pChildWindow = 0;
initWindow();
return ImplInit();
@@ -462,74 +569,186 @@ bool OpenGLContext::init(SystemChildWindow* pChildWindow)
return ImplInit();
}
-bool OpenGLContext::ImplInit()
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
+bool OpenGLContext::init(Display* dpy, Window win, int screen)
{
- SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start");
- if(m_pWindow)
- m_pWindow->setPosSizePixel(0,0,0,0);
- m_aGLWin.Width = 0;
- m_aGLWin.Height = 0;
+ if(mbInitialized)
+ return true;
-#if defined( WNT )
- m_aGLWin.hDC = GetDC(m_aGLWin.hWnd);
-#elif defined( MACOSX )
+ if (!dpy)
+ return false;
-#elif defined( IOS )
+ m_aGLWin.dpy = dpy;
+ m_aGLWin.win = win;
+ m_aGLWin.screen = screen;
- SAL_INFO("vcl.opengl", "OpenGLContext not implemented yet for iOS");
- return false;
+ Visual* pVisual = getVisual(dpy, win);
-#elif defined( ANDROID )
+ initGLWindow(pVisual);
- SAL_INFO("vcl.opengl", "OpenGLContext not implemented yet for Android");
- return false;
+ return ImplInit();
+}
-#elif defined( UNX )
-#ifdef DBG_UTIL
+bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen)
+{
+ if(mbInitialized)
+ return true;
+
+ if (!dpy)
+ return false;
+
+ SAL_INFO("vcl.opengl", "init with pixmap");
+ m_aGLWin.dpy = dpy;
+ m_aGLWin.Width = width;
+ m_aGLWin.Height = height;
+ m_aGLWin.pix = pix;
+ const int attrib_list[] = { GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ None};
+ int best_fbc = -1;
+ GLXFBConfig* config = getFBConfigForPixmap(dpy, best_fbc, mbUseDoubleBufferedRendering, nScreen);
+ if (best_fbc == -1)
+ return false;
+
+ m_aGLWin.vi = glXGetVisualFromFBConfig( dpy, config[best_fbc] );
+ m_aGLWin.glPix = glXCreatePixmap(dpy, config[best_fbc], pix, attrib_list);
- if (glXCreateContextAttribsARB && !mbRequestLegacyContext)
+ mbPixmap = true;
+
+ initOpenGLFunctionPointers();
+
+ return ImplInit();
+}
+
+bool OpenGLContext::ImplInit()
+{
+ SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start");
+#ifdef DBG_UTIL
+ if (!mbPixmap && glXCreateContextAttribsARB && !mbRequestLegacyContext)
{
int best_fbc = -1;
- const SystemEnvData* sysData(m_pChildWindow->GetSystemData());
- GLXFBConfig* pFBC = getFBConfig(sysData, best_fbc);
+ GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering);
if (!pFBC)
return false;
- int nContextAttribs[] =
+ if (best_fbc != -1)
{
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 2,
- None
- };
- m_aGLWin.ctx = glXCreateContextAttribsARB(m_aGLWin.dpy, pFBC[best_fbc], 0, GL_TRUE, nContextAttribs);
+ int nContextAttribs[] =
+ {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ None
+ };
+ m_aGLWin.ctx = glXCreateContextAttribsARB(m_aGLWin.dpy, pFBC[best_fbc], 0, GL_TRUE, nContextAttribs);
+ SAL_INFO_IF(m_aGLWin.ctx, "vcl.opengl", "created a 3.2 core context");
+ }
+ else
+ SAL_WARN("vcl.opengl", "unable to find correct FBC");
}
#endif
+
if (!m_aGLWin.ctx)
{
+ GLXContext pSharedCtx( NULL );
+
if (!m_aGLWin.dpy || !m_aGLWin.vi)
return false;
+ if( !vShareList.empty() )
+ pSharedCtx = vShareList.front();
+
m_aGLWin.ctx = m_aGLWin.dpy == 0 ? 0 : glXCreateContext(m_aGLWin.dpy,
m_aGLWin.vi,
- 0,
+ pSharedCtx,
GL_TRUE);
+
+ if( m_aGLWin.ctx )
+ vShareList.push_back( m_aGLWin.ctx );
}
+
+
if( m_aGLWin.ctx == NULL )
{
SAL_WARN("vcl.opengl", "unable to create GLX context");
return false;
}
-#endif
-#if defined( WNT )
- PIXELFORMATDESCRIPTOR PixelFormatFront = // PixelFormat Tells Windows How We Want Things To Be
+ if( !glXMakeCurrent( m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win, m_aGLWin.ctx ) )
+ {
+ SAL_WARN("vcl.opengl", "unable to select current GLX context");
+ return false;
+ }
+
+ int glxMinor, glxMajor;
+ double nGLXVersion = 0;
+ if( glXQueryVersion( m_aGLWin.dpy, &glxMajor, &glxMinor ) )
+ nGLXVersion = glxMajor + 0.1*glxMinor;
+ SAL_INFO("vcl.opengl", "available GLX version: " << nGLXVersion);
+
+ m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS );
+ SAL_INFO("vcl.opengl", "available GL extensions: " << m_aGLWin.GLExtensions);
+
+ XWindowAttributes xWinAttr;
+ XGetWindowAttributes( m_aGLWin.dpy, m_aGLWin.win, &xWinAttr );
+ m_aGLWin.Width = xWinAttr.width;
+ m_aGLWin.Height = xWinAttr.height;
+
+ if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) )
+ {
+ // enable vsync
+ typedef GLint (*glXSwapIntervalProc)(GLint);
+ glXSwapIntervalProc glXSwapInterval = (glXSwapIntervalProc) glXGetProcAddress( (const GLubyte*) "glXSwapIntervalSGI" );
+ if( glXSwapInterval )
+ {
+ int (*oldHandler)(Display* /*dpy*/, XErrorEvent* /*evnt*/);
+
+ XLockDisplay(m_aGLWin.dpy);
+ XSync(m_aGLWin.dpy, false);
+ // replace error handler temporarily
+ oldHandler = XSetErrorHandler( oglErrorHandler );
+
+ errorTriggered = false;
+
+ glXSwapInterval( 1 );
+
+ // sync so that we possibly get an XError
+ glXWaitGL();
+ XSync(m_aGLWin.dpy, false);
+
+ if( errorTriggered )
+ SAL_WARN("vcl.opengl", "error when trying to set swap interval, NVIDIA or Mesa bug?");
+ else
+ SAL_INFO("vcl.opengl", "set swap interval to 1 (enable vsync)");
+
+ // restore the error handler
+ XSetErrorHandler( oldHandler );
+ XUnlockDisplay(m_aGLWin.dpy);
+ }
+ }
+ return InitGLEW();
+}
+
+#elif defined( _WIN32 )
+
+bool OpenGLContext::init(HDC hDC, HWND hWnd)
+{
+ if (mbInitialized)
+ return false;
+
+ m_aGLWin.hDC = hDC;
+ m_aGLWin.hWnd = hWnd;
+ return ImplInit();
+}
+
+bool OpenGLContext::ImplInit()
+{
+ SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start");
+ PIXELFORMATDESCRIPTOR PixelFormatFront = // PixelFormat Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
- PFD_DRAW_TO_WINDOW |
- PFD_SUPPORT_OPENGL |
- PFD_DOUBLEBUFFER,
+ PFD_SUPPORT_OPENGL,
PFD_TYPE_RGBA, // Request An RGBA Format
(BYTE)32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
@@ -545,9 +764,18 @@ bool OpenGLContext::ImplInit()
0, 0, 0 // Layer Masks Ignored
};
+ if (mbUseDoubleBufferedRendering)
+ PixelFormatFront.dwFlags |= PFD_DOUBLEBUFFER;
+
+ if (mbRequestVirtualDevice)
+ PixelFormatFront.dwFlags |= PFD_DRAW_TO_BITMAP;
+ else
+ PixelFormatFront.dwFlags |= PFD_DRAW_TO_WINDOW;
+
// we must check whether can set the MSAA
int WindowPix = 0;
- bool bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix);
+ bool bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix,
+ mbUseDoubleBufferedRendering, mbRequestVirtualDevice);
if (bMultiSampleSupport && WindowPix != 0)
{
m_aGLWin.bMultiSampleSupported = true;
@@ -577,64 +805,37 @@ bool OpenGLContext::ImplInit()
return false;
}
+ RECT clientRect;
+ GetClientRect(WindowFromDC(m_aGLWin.hDC), &clientRect);
+ m_aGLWin.Width = clientRect.right - clientRect.left;
+ m_aGLWin.Height = clientRect.bottom - clientRect.top;
+
+ return InitGLEW();
+}
+
#elif defined( MACOSX )
+bool OpenGLContext::ImplInit()
+{
+ SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start");
NSOpenGLView* pView = getOpenGLView();
OpenGLWrapper::makeCurrent(pView);
-#elif defined( IOS )
-
-#elif defined( ANDROID )
-
-#elif defined( UNX )
- if( !glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx ) )
- {
- SAL_INFO("vcl.opengl", "unable to select current GLX context");
- return false;
- }
-
- int glxMinor, glxMajor;
- double nGLXVersion = 0;
- if( glXQueryVersion( m_aGLWin.dpy, &glxMajor, &glxMinor ) )
- nGLXVersion = glxMajor + 0.1*glxMinor;
- SAL_INFO("vcl.opengl", "available GLX version: " << nGLXVersion);
-
- m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS );
- SAL_INFO("vcl.opengl", "available GL extensions: " << m_aGLWin.GLExtensions);
-
- if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) )
- {
- // enable vsync
- typedef GLint (*glXSwapIntervalProc)(GLint);
- glXSwapIntervalProc glXSwapInterval = (glXSwapIntervalProc) glXGetProcAddress( (const GLubyte*) "glXSwapIntervalSGI" );
- if( glXSwapInterval ) {
- int (*oldHandler)(Display* /*dpy*/, XErrorEvent* /*evnt*/);
-
- // replace error handler temporarily
- oldHandler = XSetErrorHandler( oglErrorHandler );
-
- errorTriggered = false;
-
- glXSwapInterval( 1 );
-
- // sync so that we possibly get an XError
- glXWaitGL();
- XSync(m_aGLWin.dpy, false);
+ return InitGLEW();
+}
- if( errorTriggered )
- SAL_WARN("vcl.opengl", "error when trying to set swap interval, NVIDIA or Mesa bug?");
- else
- SAL_INFO("vcl.opengl", "set swap interval to 1 (enable vsync)");
+#else
- // restore the error handler
- XSetErrorHandler( oldHandler );
- }
- }
+bool OpenGLContext::ImplInit()
+{
+ SAL_INFO("vcl.opengl", "OpenGLContext not implemented for this platform");
+ return false;
+}
#endif
- //rGLRender.InitOpenGL(m_aGLWin);
-
+bool OpenGLContext::InitGLEW()
+{
static bool bGlewInit = false;
if(!bGlewInit)
{
@@ -688,7 +889,6 @@ void OpenGLContext::setWinSize(const Size& rSize)
m_aGLWin.Height = rSize.Height();
}
-
void OpenGLContext::renderToFile()
{
int iWidth = m_aGLWin.Width;
@@ -722,6 +922,7 @@ bool OpenGLContext::initWindow()
m_aGLWin.hWnd = sysData->hWnd;
}
+ m_aGLWin.hDC = GetDC(m_aGLWin.hWnd);
return true;
}
@@ -786,9 +987,16 @@ bool OpenGLContext::initWindow()
m_aGLWin.win = pChildSysData->aWindow;
m_aGLWin.screen = pChildSysData->nScreen;
+ Visual* pVisual = (Visual*)pChildSysData->pVisual;
+ initGLWindow(pVisual);
+
+ return true;
+}
+
+void OpenGLContext::initGLWindow(Visual* pVisual)
+{
// Get visual info
{
- Visual* pVisual = (Visual*)pChildSysData->pVisual;
XVisualInfo aTemplate;
aTemplate.visualid = XVisualIDFromVisual( pVisual );
int nVisuals = 0;
@@ -799,6 +1007,8 @@ bool OpenGLContext::initWindow()
}
// Check multi sample support
+ /* TODO: moggi: This is not necessarily correct in the DBG_UTIL path, as it picks
+ * an FBConfig instead ... */
int nSamples = 0;
glXGetConfig(m_aGLWin.dpy, m_aGLWin.vi, GLX_SAMPLES, &nSamples);
if( nSamples > 0 )
@@ -806,8 +1016,6 @@ bool OpenGLContext::initWindow()
m_aGLWin.GLXExtensions = glXQueryExtensionsString( m_aGLWin.dpy, m_aGLWin.screen );
SAL_INFO("vcl.opengl", "available GLX extensions: " << m_aGLWin.GLXExtensions);
-
- return true;
}
#endif
@@ -828,20 +1036,6 @@ SystemWindowData OpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool b
#elif defined( UNX )
-namespace {
-
-// we need them before glew can initialize them
-// glew needs an OpenGL context so we need to get the address manually
-void initOpenGLFunctionPointers()
-{
- glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
- glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig"); // try to find a visual for the current set of attributes
- glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
- glXCreateContextAttribsARB = (GLXContext(*) (Display*, GLXFBConfig, GLXContext, Bool, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");;
-}
-
-}
-
SystemWindowData OpenGLContext::generateWinData(vcl::Window* pParent, bool)
{
SystemWindowData aWinData;
@@ -851,23 +1045,12 @@ SystemWindowData OpenGLContext::generateWinData(vcl::Window* pParent, bool)
const SystemEnvData* sysData(pParent->GetSystemData());
Display *dpy = reinterpret_cast<Display*>(sysData->pDisplay);
+ Window win = sysData->aWindow;
if( dpy == 0 || !glXQueryExtension( dpy, NULL, NULL ) )
return aWinData;
- initOpenGLFunctionPointers();
-
- int best_fbc = -1;
- GLXFBConfig* pFBC = getFBConfig(sysData, best_fbc);
-
- XVisualInfo* vi = glXGetVisualFromFBConfig( dpy, pFBC[best_fbc] );
- if( vi )
- {
- SAL_INFO("vcl.opengl", "using VisualID " << vi->visualid);
- aWinData.pVisual = (void*)(vi->visual);
- }
-
- XFree(pFBC);
+ aWinData.pVisual = getVisual(dpy, win);
return aWinData;
}
@@ -887,7 +1070,8 @@ void OpenGLContext::makeCurrent()
#elif defined( IOS ) || defined( ANDROID )
// nothing
#elif defined( UNX )
- glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx );
+ if (!glXMakeCurrent( m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win, m_aGLWin.ctx ))
+ SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed");
#endif
}
@@ -914,7 +1098,7 @@ void OpenGLContext::swapBuffers()
#elif defined( IOS ) || defined( ANDROID )
// nothing
#elif defined( UNX )
- glXSwapBuffers(m_aGLWin.dpy, m_aGLWin.win);
+ glXSwapBuffers(m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win);
#endif
}
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index c94e290ac7f0..5823b80d63a6 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -86,7 +86,7 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
SAL_WARN("vcl.opengl", "vertex shader compile for " << rVertexShaderName << " failed : " << &VertexShaderErrorMessage[0]);
}
else
- SAL_WARN("vcl.opengl", "vertex shader compile failed without error log");
+ SAL_WARN("vcl.opengl", "vertex shader: " << rVertexShaderName << " compile failed without error log");
return 0;
}
@@ -358,4 +358,85 @@ void OpenGLHelper::checkGLError(const char* pFile, size_t nLine)
}
}
+bool OpenGLHelper::supportsVCLOpenGL()
+{
+ static bool bDisableGL = !getenv("SAL_DISABLEGL");
+ return bDisableGL;
+}
+
+#if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
+
+bool OpenGLHelper::GetVisualInfo(Display* pDisplay, int nScreen, XVisualInfo& rVI)
+{
+ XVisualInfo* pVI;
+ int aAttrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_DEPTH_SIZE, 24,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ pVI = glXChooseVisual( pDisplay, nScreen, aAttrib );
+ if( !pVI )
+ return false;
+
+ rVI = *pVI;
+ XFree( pVI );
+
+ return true;
+}
+
+GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted )
+{
+ int nScreen = DefaultScreen( pDisplay );
+ GLXFBConfig *aFbConfigs;
+ int i, nFbConfigs, nValue;
+
+ aFbConfigs = glXGetFBConfigs( pDisplay, nScreen, &nFbConfigs );
+ for( i = 0; i < nFbConfigs; i++ )
+ {
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DRAWABLE_TYPE, &nValue );
+ if( !(nValue & GLX_PIXMAP_BIT) )
+ continue;
+
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &nValue );
+ if( !(nValue & GLX_TEXTURE_2D_BIT_EXT) )
+ continue;
+
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_DEPTH_SIZE, &nValue );
+ if( nValue != 24 )
+ continue;
+
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_RED_SIZE, &nValue );
+ if( nValue != 8 )
+ continue;
+ SAL_INFO( "vcl.opengl", "Red is " << nValue );
+
+ // TODO: lfrb: Make it configurable wrt RGB/RGBA
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &nValue );
+ if( nValue == False )
+ {
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &nValue );
+ if( nValue == False )
+ continue;
+ }
+
+ glXGetFBConfigAttrib( pDisplay, aFbConfigs[i], GLX_Y_INVERTED_EXT, &nValue );
+ bInverted = (nValue == True) ? true : false;
+
+ break;
+ }
+
+ if( i == nFbConfigs )
+ {
+ SAL_WARN( "vcl.opengl", "Unable to find FBconfig for pixmap texturing" );
+ return 0;
+ }
+
+ return aFbConfigs[i];
+}
+
+#endif
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index a191b8b2c703..20e6367ac30c 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -457,8 +457,7 @@ Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
if( pSalBmp )
{
- ImpBitmap* pImpBmp = new ImpBitmap;
- pImpBmp->ImplSetSalBitmap( pSalBmp );
+ ImpBitmap* pImpBmp = new ImpBitmap(pSalBmp);
aBmp.ImplSetImpBitmap( pImpBmp );
}
}
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 3c9e519cc71d..ad7779dc597d 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -839,4 +839,11 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
return bDrawn;
}
+bool OutputDevice::SwapBuffers()
+{
+ if( !mpGraphics && !AcquireGraphics() )
+ return false;
+ return mpGraphics->SwapBuffers();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/polygon.cxx b/vcl/source/outdev/polygon.cxx
index 39c2b6807a77..03fa16888ea3 100644
--- a/vcl/source/outdev/polygon.cxx
+++ b/vcl/source/outdev/polygon.cxx
@@ -231,7 +231,7 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly )
// Caution: This method is nearly the same as
// OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
-// so when changes are made here do not forget to make change sthere, too
+// so when changes are made here do not forget to make changes there, too
void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
{
diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index 7ec329cc1388..b3576db29689 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -278,6 +278,8 @@ void Window::ImplCallOverlapPaint()
// - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
// because we were called from the Sal layer
ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
+ OutputDevice *pOutDev = GetOutDev();
+ pOutDev->SwapBuffers();
}
}
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index 88be46307f7d..5803733c4ca6 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -67,10 +67,14 @@
#include <unx/sm.hxx>
#include <unx/wmadaptor.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+
#include <osl/socket.h>
#include <poll.h>
#include <boost/scoped_array.hpp>
+#include <officecfg/Office/Common.hxx>
+
using namespace vcl_sal;
#define SALCOLOR_WHITE MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF )
@@ -187,6 +191,10 @@ bool SalDisplay::BestVisual( Display *pDisplay,
if( nVID && sal_GetVisualInfo( pDisplay, nVID, rVI ) )
return rVI.visualid == nDefVID;
+ bool bUseOpenGL = officecfg::Office::Common::VCL::UseOpenGL::get();
+ if( bUseOpenGL && OpenGLHelper::GetVisualInfo( pDisplay, nScreen, rVI ) )
+ return rVI.visualid == nDefVID;
+
XVisualInfo aVI;
aVI.screen = nScreen;
// get all visuals
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
new file mode 100644
index 000000000000..5b31b92fd42a
--- /dev/null
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -0,0 +1,660 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "cairotextrender.hxx"
+
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sysdata.hxx>
+
+#include "generic/printergfx.hxx"
+#include "generic/genpspgraphics.h"
+#include "generic/geninst.h"
+#include "PhysicalFontFace.hxx"
+#include "impfont.hxx"
+
+#include <config_graphite.h>
+#if ENABLE_GRAPHITE
+#include <graphite_layout.hxx>
+#include <graphite_serverfont.hxx>
+#endif
+
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+
+CairoTextRender::CairoTextRender(bool bPrinter):
+ mbPrinter(bPrinter),
+ nTextColor_(MAKE_SALCOLOR(0x00, 0x00, 0x00)) //black
+{
+ for( int i = 0; i < MAX_FALLBACK; ++i )
+ mpServerFont[i] = NULL;
+
+#if ENABLE_GRAPHITE
+ // check if graphite fonts have been disabled
+ static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" );
+ bDisableGraphite_ = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
+#endif
+}
+
+bool CairoTextRender::setFont( const FontSelectPattern *pEntry, int nFallbackLevel )
+{
+ // release all no longer needed font resources
+ for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
+ {
+ if( mpServerFont[i] != NULL )
+ {
+ // old server side font is no longer referenced
+ GlyphCache::GetInstance().UncacheFont( *mpServerFont[i] );
+ mpServerFont[i] = NULL;
+ }
+ }
+
+ // return early if there is no new font
+ if( !pEntry )
+ return false;
+
+ // return early if this is not a valid font for this graphics
+ if( !pEntry->mpFontData )
+ return false;
+
+ // handle the request for a non-native X11-font => use the GlyphCache
+ ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
+ if( pServerFont != NULL )
+ {
+ // ignore fonts with e.g. corrupted font files
+ if( !pServerFont->TestFont() )
+ {
+ GlyphCache::GetInstance().UncacheFont( *pServerFont );
+ return false;
+ }
+
+ // register to use the font
+ mpServerFont[ nFallbackLevel ] = pServerFont;
+
+ // apply font specific-hint settings if needed
+ // TODO: also disable it for reference devices
+ if( !mbPrinter )
+ {
+ ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry );
+ pSFE->HandleFontOptions();
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize);
+
+void ImplServerFontEntry::HandleFontOptions( void )
+{
+ if( !mpServerFont )
+ return;
+ if( !mbGotFontOptions )
+ {
+ // get and cache the font options
+ mbGotFontOptions = true;
+ mpFontOptions.reset(GetFCFontOptions( *maFontSelData.mpFontData,
+ maFontSelData.mnHeight ));
+ }
+ // apply the font options
+ mpServerFont->SetFontOptions( mpFontOptions );
+}
+
+CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
+int CairoFontsCache::mnRefCount = 0;
+
+CairoFontsCache::CairoFontsCache()
+{
+ ++mnRefCount;
+}
+
+CairoFontsCache::~CairoFontsCache()
+{
+ --mnRefCount;
+ if (!mnRefCount && !maLRUFonts.empty())
+ {
+ LRUFonts::iterator aEnd = maLRUFonts.end();
+ for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
+ cairo_font_face_destroy((cairo_font_face_t*)aI->first);
+ }
+}
+
+void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId)
+{
+ maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
+ if (maLRUFonts.size() > 8)
+ {
+ cairo_font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
+ maLRUFonts.pop_back();
+ }
+}
+
+void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
+{
+ LRUFonts::iterator aEnd = maLRUFonts.end();
+ for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
+ if (aI->second == rId)
+ return aI->first;
+ return NULL;
+}
+
+namespace
+{
+ bool hasRotation(int nRotation)
+ {
+ return nRotation != 0;
+ }
+
+ double toRadian(int nDegree10th)
+ {
+ return (3600 - (nDegree10th)) * M_PI / 1800.0;
+ }
+}
+
+void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
+{
+ std::vector<cairo_glyph_t> cairo_glyphs;
+ std::vector<int> glyph_extrarotation;
+ cairo_glyphs.reserve( 256 );
+
+ Point aPos;
+ sal_GlyphId aGlyphId;
+ for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
+ {
+ cairo_glyph_t aGlyph;
+ aGlyph.index = aGlyphId & GF_IDXMASK;
+ aGlyph.x = aPos.X();
+ aGlyph.y = aPos.Y();
+ cairo_glyphs.push_back(aGlyph);
+
+ switch (aGlyphId & GF_ROTMASK)
+ {
+ case GF_ROTL: // left
+ glyph_extrarotation.push_back(1);
+ break;
+ case GF_ROTR: // right
+ glyph_extrarotation.push_back(-1);
+ break;
+ default:
+ glyph_extrarotation.push_back(0);
+ break;
+ }
+ }
+
+ if (cairo_glyphs.empty())
+ return;
+
+ cairo_surface_t *surface = getCairoSurface();
+
+ DBG_ASSERT( surface!=NULL, "no cairo surface for text" );
+ if( !surface )
+ return;
+
+ /*
+ * It might be ideal to cache surface and cairo context between calls and
+ * only destroy it when the drawable changes, but to do that we need to at
+ * least change the SalFrame etc impls to dtor the SalGraphics *before* the
+ * destruction of the windows they reference
+ */
+ cairo_t *cr = cairo_create(surface);
+ cairo_surface_destroy(surface);
+
+ if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
+ cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions));
+
+ clipRegion(cr);
+
+ cairo_set_source_rgb(cr,
+ SALCOLOR_RED(nTextColor_)/255.0,
+ SALCOLOR_GREEN(nTextColor_)/255.0,
+ SALCOLOR_BLUE(nTextColor_)/255.0);
+
+ ServerFont& rFont = rLayout.GetServerFont();
+
+ FT_Face aFace = rFont.GetFtFace();
+ CairoFontsCache::CacheId aId;
+ aId.maFace = aFace;
+ aId.mpOptions = rFont.GetFontOptions().get();
+ aId.mbEmbolden = rFont.NeedsArtificialBold();
+
+ cairo_matrix_t m;
+ const FontSelectPattern& rFSD = rFont.GetFontSelData();
+ int nHeight = rFSD.mnHeight;
+ int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
+
+ std::vector<int>::const_iterator aEnd = glyph_extrarotation.end();
+ std::vector<int>::const_iterator aStart = glyph_extrarotation.begin();
+ std::vector<int>::const_iterator aI = aStart;
+ while (aI != aEnd)
+ {
+ int nGlyphRotation = *aI;
+
+ std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
+
+ size_t nStartIndex = std::distance(aStart, aI);
+ size_t nLen = std::distance(aI, aNext);
+
+ aId.mbVerticalMetrics = nGlyphRotation != 0.0;
+ cairo_font_face_t* font_face = (cairo_font_face_t*)CairoFontsCache::FindCachedFont(aId);
+ if (!font_face)
+ {
+ const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
+ void *pPattern = pOptions ? pOptions->GetPattern(aFace, aId.mbEmbolden, aId.mbVerticalMetrics) : NULL;
+ if (pPattern)
+ font_face = cairo_ft_font_face_create_for_pattern(reinterpret_cast<FcPattern*>(pPattern));
+ if (!font_face)
+ font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(aFace), rFont.GetLoadFlags());
+ CairoFontsCache::CacheFont(font_face, aId);
+ }
+ cairo_set_font_face(cr, font_face);
+
+ cairo_set_font_size(cr, nHeight);
+
+ cairo_matrix_init_identity(&m);
+
+ if (rLayout.GetOrientation())
+ cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
+
+ cairo_matrix_scale(&m, nWidth, nHeight);
+
+ if (nGlyphRotation)
+ {
+ cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
+
+ cairo_matrix_t em_square;
+ cairo_matrix_init_identity(&em_square);
+ cairo_get_matrix(cr, &em_square);
+
+ cairo_matrix_scale(&em_square, aFace->units_per_EM,
+ aFace->units_per_EM);
+ cairo_set_matrix(cr, &em_square);
+
+ cairo_font_extents_t font_extents;
+ cairo_font_extents(cr, &font_extents);
+
+ cairo_matrix_init_identity(&em_square);
+ cairo_set_matrix(cr, &em_square);
+
+ //gives the same positions as pre-cairo conversion, but I don't
+ //like them
+ double xdiff = 0.0;
+ double ydiff = 0.0;
+ if (nGlyphRotation == 1)
+ {
+ ydiff = font_extents.ascent/nHeight;
+ xdiff = -font_extents.descent/nHeight;
+ }
+ else if (nGlyphRotation == -1)
+ {
+ cairo_text_extents_t text_extents;
+ cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
+ &text_extents);
+
+ xdiff = -text_extents.x_advance/nHeight;
+ //to restore an apparent bug in the original X11 impl, replace
+ //nHeight with nWidth below
+ xdiff += font_extents.descent/nHeight;
+ }
+ cairo_matrix_translate(&m, xdiff, ydiff);
+ }
+
+ if (rFont.NeedsArtificialItalic())
+ {
+ cairo_matrix_t shear;
+ cairo_matrix_init_identity(&shear);
+ shear.xy = -shear.xx * 0x6000L / 0x10000L;
+ cairo_matrix_multiply(&m, &shear, &m);
+ }
+
+ cairo_set_font_matrix(cr, &m);
+ cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
+
+#if OSL_DEBUG_LEVEL > 2
+ //draw origin
+ cairo_save (cr);
+ cairo_rectangle (cr, cairo_glyphs[nStartIndex].x, cairo_glyphs[nStartIndex].y, 5, 5);
+ cairo_set_source_rgba (cr, 1, 0, 0, 0.80);
+ cairo_fill (cr);
+ cairo_restore (cr);
+#endif
+
+ aI = aNext;
+ }
+
+ drawSurface(cr);
+ cairo_destroy(cr);
+}
+
+const FontCharMapPtr CairoTextRender::GetFontCharMap() const
+{
+ if( !mpServerFont[0] )
+ return NULL;
+
+ const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
+ return pFCMap;
+}
+
+bool CairoTextRender::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const
+{
+ if (!mpServerFont[0])
+ return false;
+ return mpServerFont[0]->GetFontCapabilities(rGetImplFontCapabilities);
+}
+
+// SalGraphics
+
+sal_uInt16 CairoTextRender::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
+{
+ sal_uInt16 nRetVal = 0;
+ if( !setFont( pEntry, nFallbackLevel ) )
+ nRetVal |= SAL_SETFONT_BADFONT;
+ if( mbPrinter || (mpServerFont[ nFallbackLevel ] != NULL) )
+ nRetVal |= SAL_SETFONT_USEDRAWTEXTARRAY;
+ return nRetVal;
+}
+
+void
+CairoTextRender::SetTextColor( SalColor nSalColor )
+{
+ if( nTextColor_ != nSalColor )
+ {
+ nTextColor_ = nSalColor;
+ }
+}
+
+bool CairoTextRender::AddTempDevFont( PhysicalFontCollection* pFontCollection,
+ const OUString& rFileURL,
+ const OUString& rFontName )
+{
+ // inform PSP font manager
+ OUString aUSystemPath;
+ OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFileURL, aUSystemPath ) );
+ rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
+ OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) );
+ psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+ std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName );
+ if( aFontIds.empty() )
+ return false;
+
+ GlyphCache& rGC = getPlatformGlyphCache();
+
+ for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI)
+ {
+ // prepare font data
+ psp::FastPrintFontInfo aInfo;
+ rMgr.getFontFastInfo( *aI, aInfo );
+ aInfo.m_aFamilyName = rFontName;
+
+ // inform glyph cache of new font
+ ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
+ aDFA.mnQuality += 5800;
+
+ int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
+
+ const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
+ rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
+ }
+
+ // announce new font to device's font list
+ rGC.AnnounceFonts( pFontCollection );
+ return true;
+}
+
+void CairoTextRender::ClearDevFontCache()
+{
+ GlyphCache& rGC = getPlatformGlyphCache();
+ rGC.ClearFontCache();
+}
+
+void CairoTextRender::GetDevFontList( PhysicalFontCollection* pFontCollection )
+{
+ // prepare the GlyphCache using psprint's font infos
+ GlyphCache& rGC = getPlatformGlyphCache();
+
+ psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+ ::std::list< psp::fontID > aList;
+ ::std::list< psp::fontID >::iterator it;
+ psp::FastPrintFontInfo aInfo;
+ rMgr.getFontList( aList );
+ for( it = aList.begin(); it != aList.end(); ++it )
+ {
+ if( !rMgr.getFontFastInfo( *it, aInfo ) )
+ continue;
+
+ // normalize face number to the GlyphCache
+ int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
+
+ // inform GlyphCache about this font provided by the PsPrint subsystem
+ ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
+ aDFA.mnQuality += 4096;
+ const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
+ rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
+ }
+
+ // announce glyphcache fonts
+ rGC.AnnounceFonts( pFontCollection );
+
+ // register platform specific font substitutions if available
+ SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
+
+ ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
+}
+
+void cairosubcallback(void* pPattern)
+{
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
+ if( !pFontOptions )
+ return;
+ cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
+ static_cast<FcPattern*>(pPattern));
+}
+
+ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)
+{
+ psp::FastPrintFontInfo aInfo;
+
+ aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
+ aInfo.m_eItalic = rFontAttributes.GetSlant();
+ aInfo.m_eWeight = rFontAttributes.GetWeight();
+ aInfo.m_eWidth = rFontAttributes.GetWidthType();
+
+ const psp::PrintFontManager& rPFM = psp::PrintFontManager::get();
+ return rPFM.getFontOptions(aInfo, nSize, cairosubcallback);
+}
+
+void
+CairoTextRender::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel )
+{
+ if( nFallbackLevel >= MAX_FALLBACK )
+ return;
+
+ if( mpServerFont[nFallbackLevel] != NULL )
+ {
+ long rDummyFactor;
+ mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
+ }
+}
+
+bool CairoTextRender::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
+{
+ const int nLevel = aGlyphId >> GF_FONTSHIFT;
+ if( nLevel >= MAX_FALLBACK )
+ return false;
+
+ ServerFont* pSF = mpServerFont[ nLevel ];
+ if( !pSF )
+ return false;
+
+ aGlyphId &= GF_IDXMASK;
+ const GlyphMetric& rGM = pSF->GetGlyphMetric(aGlyphId);
+ Rectangle aRect( rGM.GetOffset(), rGM.GetSize() );
+
+ if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
+ {
+ double nCos = pSF->mnCos / 65536.0;
+ double nSin = pSF->mnSin / 65536.0;
+ rRect.Left() = nCos*aRect.Left() + nSin*aRect.Top();
+ rRect.Top() = -nSin*aRect.Left() - nCos*aRect.Top();
+
+ rRect.Right() = nCos*aRect.Right() + nSin*aRect.Bottom();
+ rRect.Bottom() = -nSin*aRect.Right() - nCos*aRect.Bottom();
+ }
+ else
+ rRect = aRect;
+
+ return true;
+}
+
+bool CairoTextRender::GetGlyphOutline( sal_GlyphId aGlyphId,
+ ::basegfx::B2DPolyPolygon& rPolyPoly )
+{
+ const int nLevel = aGlyphId >> GF_FONTSHIFT;
+ if( nLevel >= MAX_FALLBACK )
+ return false;
+
+ ServerFont* pSF = mpServerFont[ nLevel ];
+ if( !pSF )
+ return false;
+
+ aGlyphId &= GF_IDXMASK;
+ if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) )
+ return true;
+
+ return false;
+}
+
+SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
+{
+ SalLayout* pLayout = NULL;
+
+ if( mpServerFont[ nFallbackLevel ]
+ && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
+ {
+#if ENABLE_GRAPHITE
+ // Is this a Graphite font?
+ if (!bDisableGraphite_ &&
+ GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
+ {
+ pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
+ }
+ else
+#endif
+ pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
+ }
+
+ return pLayout;
+}
+
+SystemFontData CairoTextRender::GetSysFontData( int nFallbackLevel ) const
+{
+ SystemFontData aSysFontData;
+ aSysFontData.nSize = sizeof( SystemFontData );
+ aSysFontData.nFontId = 0;
+
+ if (nFallbackLevel >= MAX_FALLBACK) nFallbackLevel = MAX_FALLBACK - 1;
+ if (nFallbackLevel < 0 ) nFallbackLevel = 0;
+
+ if (mpServerFont[nFallbackLevel] != NULL)
+ {
+ ServerFont* rFont = mpServerFont[nFallbackLevel];
+ aSysFontData.nFontId = rFont->GetFtFace();
+ aSysFontData.nFontFlags = rFont->GetLoadFlags();
+ aSysFontData.bFakeBold = rFont->NeedsArtificialBold();
+ aSysFontData.bFakeItalic = rFont->NeedsArtificialItalic();
+ aSysFontData.bAntialias = rFont->GetAntialiasAdvice();
+ aSysFontData.bVerticalCharacterType = rFont->GetFontSelData().mbVertical;
+ }
+
+ return aSysFontData;
+}
+
+bool CairoTextRender::CreateFontSubset(
+ const OUString& rToFile,
+ const PhysicalFontFace* pFont,
+ sal_GlyphId* pGlyphIds,
+ sal_uInt8* pEncoding,
+ sal_Int32* pWidths,
+ int nGlyphCount,
+ FontSubsetInfo& rInfo
+ )
+{
+ // in this context the pFont->GetFontId() is a valid PSP
+ // font since they are the only ones left after the PDF
+ // export has filtered its list of subsettable fonts (for
+ // which this method was created). The correct way would
+ // be to have the GlyphCache search for the PhysicalFontFace pFont
+ psp::fontID aFont = pFont->GetFontId();
+
+ psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+ bool bSuccess = rMgr.createFontSubset( rInfo,
+ aFont,
+ rToFile,
+ pGlyphIds,
+ pEncoding,
+ pWidths,
+ nGlyphCount );
+ return bSuccess;
+}
+
+const void* CairoTextRender::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
+{
+ // in this context the pFont->GetFontId() is a valid PSP
+ // font since they are the only ones left after the PDF
+ // export has filtered its list of subsettable fonts (for
+ // which this method was created). The correct way would
+ // be to have the GlyphCache search for the PhysicalFontFace pFont
+ psp::fontID aFont = pFont->GetFontId();
+ return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
+}
+
+void CairoTextRender::FreeEmbedFontData( const void* pData, long nLen )
+{
+ GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
+}
+
+const Ucs2SIntMap* CairoTextRender::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
+{
+ // in this context the pFont->GetFontId() is a valid PSP
+ // font since they are the only ones left after the PDF
+ // export has filtered its list of subsettable fonts (for
+ // which this method was created). The correct way would
+ // be to have the GlyphCache search for the PhysicalFontFace pFont
+ psp::fontID aFont = pFont->GetFontId();
+ return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
+}
+
+void CairoTextRender::GetGlyphWidths( const PhysicalFontFace* pFont,
+ bool bVertical,
+ Int32Vector& rWidths,
+ Ucs2UIntMap& rUnicodeEnc )
+{
+ // in this context the pFont->GetFontId() is a valid PSP
+ // font since they are the only ones left after the PDF
+ // export has filtered its list of subsettable fonts (for
+ // which this method was created). The correct way would
+ // be to have the GlyphCache search for the PhysicalFontFace pFont
+ psp::fontID aFont = pFont->GetFontId();
+ GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
new file mode 100644
index 000000000000..172ebd6314fb
--- /dev/null
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -0,0 +1,1850 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <prex.h>
+#include <X11/Xproto.h>
+#include <postx.h>
+
+#include "gdiimpl.hxx"
+
+#include "vcl/salbtype.hxx"
+#include <vcl/gradient.hxx>
+
+#include "unx/salunx.h"
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+#include "unx/salbmp.h"
+#include "unx/salgdi.h"
+#include "unx/salframe.h"
+#include "unx/salvd.h"
+#include <unx/x11/xlimits.hxx>
+#include "xrender_peer.hxx"
+
+#include "outdata.hxx"
+
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygontools.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+#include "basegfx/polygon/b2dpolygonclipper.hxx"
+#include "basegfx/polygon/b2dlinegeometry.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
+#include "basegfx/matrix/b2dhommatrixtools.hxx"
+#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
+#include "basegfx/polygon/b2dtrapezoid.hxx"
+
+#undef SALGDI2_TESTTRANS
+
+#if (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable ) \
+{ \
+ XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(), \
+ 0, 0, \
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight, \
+ 0, 0 ); \
+}
+#else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable )
+#endif // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+
+#define STATIC_POINTS 64
+
+class SalPolyLine
+{
+ XPoint Points_[STATIC_POINTS];
+ XPoint *pFirst_;
+public:
+ SalPolyLine(sal_uLong nPoints, const SalPoint *p)
+ : pFirst_(nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_)
+ {
+ for( sal_uLong i = 0; i < nPoints; i++ )
+ {
+ pFirst_[i].x = (short)p[i].mnX;
+ pFirst_[i].y = (short)p[i].mnY;
+ }
+ pFirst_[nPoints] = pFirst_[0]; // close polyline
+ }
+
+ ~SalPolyLine()
+ {
+ if( pFirst_ != Points_ )
+ delete [] pFirst_;
+ }
+
+ XPoint &operator [] ( sal_uLong n ) const
+ {
+ return pFirst_[n];
+ }
+};
+
+#undef STATIC_POINTS
+
+namespace
+{
+ void setForeBack(XGCValues& rValues, const SalColormap& rColMap, const SalBitmap& rSalBitmap)
+ {
+ rValues.foreground = rColMap.GetWhitePixel();
+ rValues.background = rColMap.GetBlackPixel();
+
+ //fdo#33455 and fdo#80160 handle 1 bit depth pngs with palette entries
+ //to set fore/back colors
+ SalBitmap& rBitmap = const_cast<SalBitmap&>(rSalBitmap);
+ if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(true))
+ {
+ const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
+ if (rPalette.GetEntryCount() == 2)
+ {
+ const BitmapColor aWhite(rPalette[rPalette.GetBestIndex(Color(COL_WHITE))]);
+ rValues.foreground = rColMap.GetPixel(ImplColorToSal(aWhite));
+
+ const BitmapColor aBlack(rPalette[rPalette.GetBestIndex(Color(COL_BLACK))]);
+ rValues.background = rColMap.GetPixel(ImplColorToSal(aBlack));
+ }
+ rBitmap.ReleaseBuffer(pBitmapBuffer, true);
+ }
+ }
+}
+
+X11SalGraphicsImpl::X11SalGraphicsImpl(X11SalGraphics& rParent):
+ mrParent(rParent),
+ mnBrushColor( MAKE_SALCOLOR( 0xFF, 0xFF, 0XFF ) ),
+ mpBrushGC(NULL),
+ mnBrushPixel(0),
+ mbPenGC(false),
+ mbBrushGC(false),
+ mbMonoGC(false),
+ mbCopyGC(false),
+ mbInvertGC(false),
+ mbInvert50GC(false),
+ mbStippleGC(false),
+ mbTrackingGC(false),
+ mbDitherBrush(false),
+ mbXORMode(false),
+ mpPenGC(NULL),
+ mnPenColor( MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) ),
+ mnPenPixel(0),
+ mpMonoGC(NULL),
+ mpCopyGC(NULL),
+ mpMaskGC(NULL),
+ mpInvertGC(NULL),
+ mpInvert50GC(NULL),
+ mpStippleGC(NULL),
+ mpTrackingGC(NULL)
+{
+}
+
+X11SalGraphicsImpl::~X11SalGraphicsImpl()
+{
+}
+
+void X11SalGraphicsImpl::Init()
+{
+ mnPenPixel = mrParent.GetPixel( mnPenColor );
+ mnBrushPixel = mrParent.GetPixel( mnBrushColor );
+}
+
+X11Pixmap* X11SalGraphicsImpl::GetPixmapFromScreen( const Rectangle& rRect )
+{
+ //TODO lfrb: don't hardcode the depth
+ Display* pDpy = mrParent.GetXDisplay();
+ X11Pixmap* pPixmap = new X11Pixmap( pDpy, mrParent.GetScreenNumber(),
+ rRect.GetWidth(), rRect.GetHeight(), 24 );
+ GC aTmpGC = XCreateGC( pDpy, pPixmap->GetPixmap(), 0, NULL );
+
+ if( !pPixmap || !aTmpGC )
+ {
+ if ( pPixmap )
+ delete pPixmap;
+ if ( aTmpGC )
+ XFreeGC( pDpy, aTmpGC );
+ SAL_WARN( "vcl", "Could not get valid pixmap from screen" );
+ return NULL;
+ }
+
+ // Copy the background of the screen into a composite pixmap
+ mrParent.CopyScreenArea( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(), mrParent.GetScreenNumber(),
+ mrParent.GetVisual().GetDepth(),
+ pPixmap->GetDrawable(), pPixmap->GetScreen(),
+ pPixmap->GetDepth(),
+ aTmpGC,
+ rRect.Left(), rRect.Top(),
+ rRect.GetWidth(), rRect.GetHeight(),
+ 0, 0 );
+
+ XFreeGC( pDpy, aTmpGC );
+ return pPixmap;
+}
+
+bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
+{
+ GC aFontGC = mrParent.GetFontGC();
+
+ // The GC can't be null, otherwise we'd have no clip region
+ if( aFontGC == NULL )
+ {
+ SAL_WARN( "vcl", "no valid GC to render pixmap" );
+ return false;
+ }
+
+ if( !pPixmap )
+ return false;
+
+ mrParent.CopyScreenArea( mrParent.GetXDisplay(),
+ pPixmap->GetDrawable(), pPixmap->GetScreen(),
+ pPixmap->GetDepth(),
+ mrParent.GetDrawable(), mrParent.m_nXScreen,
+ mrParent.GetVisual().GetDepth(),
+ aFontGC,
+ 0, 0,
+ pPixmap->GetWidth(), pPixmap->GetHeight(),
+ nX, nY );
+ return true;
+}
+
+XID X11SalGraphicsImpl::GetXRenderPicture()
+{
+ XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+
+ if( !mrParent.m_aXRenderPicture )
+ {
+ // check xrender support for matching visual
+ XRenderPictFormat* pXRenderFormat = mrParent.GetXRenderFormat();
+ if( !pXRenderFormat )
+ return 0;
+ // get the matching xrender target for drawable
+ mrParent.m_aXRenderPicture = rRenderPeer.CreatePicture( mrParent.hDrawable_, pXRenderFormat, 0, NULL );
+ }
+
+ {
+ // reset clip region
+ // TODO: avoid clip reset if already done
+ XRenderPictureAttributes aAttr;
+ aAttr.clip_mask = None;
+ rRenderPeer.ChangePicture( mrParent.m_aXRenderPicture, CPClipMask, &aAttr );
+ }
+
+ return mrParent.m_aXRenderPicture;
+}
+
+void X11SalGraphicsImpl::freeResources()
+{
+ Display *pDisplay = mrParent.GetXDisplay();
+
+ if( mpPenGC ) XFreeGC( pDisplay, mpPenGC ), mpPenGC = None;
+ if( mpBrushGC ) XFreeGC( pDisplay, mpBrushGC ), mpBrushGC = None;
+ if( mpMonoGC ) XFreeGC( pDisplay, mpMonoGC ), mpMonoGC = None;
+ if( mpTrackingGC ) XFreeGC( pDisplay, mpTrackingGC ), mpTrackingGC = None;
+ if( mpCopyGC ) XFreeGC( pDisplay, mpCopyGC ), mpCopyGC = None;
+ if( mpMaskGC ) XFreeGC( pDisplay, mpMaskGC ), mpMaskGC = None;
+ if( mpInvertGC ) XFreeGC( pDisplay, mpInvertGC ), mpInvertGC = None;
+ if( mpInvert50GC ) XFreeGC( pDisplay, mpInvert50GC ), mpInvert50GC = None;
+ if( mpStippleGC ) XFreeGC( pDisplay, mpStippleGC ), mpStippleGC = None;
+ mbTrackingGC = mbPenGC = mbBrushGC = mbMonoGC = mbCopyGC = mbInvertGC = mbInvert50GC = mbStippleGC = false;
+}
+
+GC X11SalGraphicsImpl::CreateGC( Drawable hDrawable, unsigned long nMask )
+{
+ XGCValues values;
+
+ values.graphics_exposures = False;
+ values.foreground = mrParent.m_pColormap->GetBlackPixel()
+ ^ mrParent.m_pColormap->GetWhitePixel();
+ values.function = GXxor;
+ values.line_width = 1;
+ values.fill_style = FillStippled;
+ values.stipple = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
+ values.subwindow_mode = ClipByChildren;
+
+ return XCreateGC( mrParent.GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
+}
+
+inline GC X11SalGraphicsImpl::GetCopyGC()
+{
+ if( mbXORMode ) return GetInvertGC();
+
+ if( !mpCopyGC )
+ mpCopyGC = CreateGC( mrParent.GetDrawable() );
+
+ if( !mbCopyGC )
+ {
+ mrParent.SetClipRegion( mpCopyGC );
+ mbCopyGC = true;
+ }
+ return mpCopyGC;
+}
+
+GC X11SalGraphicsImpl::GetTrackingGC()
+{
+ const char dash_list[2] = {2, 2};
+
+ if( !mpTrackingGC )
+ {
+ XGCValues values;
+
+ values.graphics_exposures = False;
+ values.foreground = mrParent.m_pColormap->GetBlackPixel()
+ ^ mrParent.m_pColormap->GetWhitePixel();
+ values.function = GXxor;
+ values.line_width = 1;
+ values.line_style = LineOnOffDash;
+
+ mpTrackingGC = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
+ GCGraphicsExposures | GCForeground | GCFunction
+ | GCLineWidth | GCLineStyle,
+ &values );
+ XSetDashes( mrParent.GetXDisplay(), mpTrackingGC, 0, dash_list, 2 );
+ }
+
+ if( !mbTrackingGC )
+ {
+ mrParent.SetClipRegion( mpTrackingGC );
+ mbTrackingGC = true;
+ }
+
+ return mpTrackingGC;
+}
+
+inline GC X11SalGraphicsImpl::GetMonoGC( Pixmap hPixmap )
+{
+ if( !mpMonoGC )
+ mpMonoGC = CreateGC( hPixmap );
+
+ if( !mbMonoGC )
+ {
+ mrParent.SetClipRegion( mpMonoGC );
+ mbMonoGC = true;
+ }
+
+ return mpMonoGC;
+}
+
+GC X11SalGraphicsImpl::GetInvertGC()
+{
+ if( !mpInvertGC )
+ mpInvertGC = CreateGC( mrParent.GetDrawable(),
+ GCGraphicsExposures
+ | GCForeground
+ | GCFunction
+ | GCLineWidth );
+
+ if( !mbInvertGC )
+ {
+ mrParent.SetClipRegion( mpInvertGC );
+ mbInvertGC = true;
+ }
+ return mpInvertGC;
+}
+
+GC X11SalGraphicsImpl::GetInvert50GC()
+{
+ if( !mpInvert50GC )
+ {
+ XGCValues values;
+
+ values.graphics_exposures = False;
+ values.foreground = mrParent.m_pColormap->GetWhitePixel();
+ values.background = mrParent.m_pColormap->GetBlackPixel();
+ values.function = GXinvert;
+ values.line_width = 1;
+ values.line_style = LineSolid;
+ unsigned long nValueMask =
+ GCGraphicsExposures
+ | GCForeground
+ | GCBackground
+ | GCFunction
+ | GCLineWidth
+ | GCLineStyle
+ | GCFillStyle
+ | GCStipple;
+
+ char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
+ if( pEnv && ! strcasecmp( pEnv, "true" ) )
+ {
+ values.fill_style = FillSolid;
+ nValueMask &= ~ GCStipple;
+ }
+ else
+ {
+ values.fill_style = FillStippled;
+ values.stipple = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
+ }
+
+ mpInvert50GC = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
+ nValueMask,
+ &values );
+ }
+
+ if( !mbInvert50GC )
+ {
+ mrParent.SetClipRegion( mpInvert50GC );
+ mbInvert50GC = true;
+ }
+ return mpInvert50GC;
+}
+
+inline GC X11SalGraphicsImpl::GetStippleGC()
+{
+ if( !mpStippleGC )
+ mpStippleGC = CreateGC( mrParent.GetDrawable(),
+ GCGraphicsExposures
+ | GCFillStyle
+ | GCLineWidth );
+
+ if( !mbStippleGC )
+ {
+ XSetFunction( mrParent.GetXDisplay(), mpStippleGC, mbXORMode ? GXxor : GXcopy );
+ mrParent.SetClipRegion( mpStippleGC );
+ mbStippleGC = true;
+ }
+
+ return mpStippleGC;
+}
+
+GC X11SalGraphicsImpl::SelectBrush()
+{
+ Display *pDisplay = mrParent.GetXDisplay();
+
+ DBG_ASSERT( mnBrushColor != SALCOLOR_NONE, "Brush Transparent" );
+
+ if( !mpBrushGC )
+ {
+ XGCValues values;
+ values.subwindow_mode = ClipByChildren;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = False;
+
+ mpBrushGC = XCreateGC( pDisplay, mrParent.hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !mbBrushGC )
+ {
+ if( !mbDitherBrush )
+ {
+ XSetFillStyle ( pDisplay, mpBrushGC, FillSolid );
+ XSetForeground( pDisplay, mpBrushGC, mnBrushPixel );
+ if( mrParent.bPrinter_ )
+ XSetTile( pDisplay, mpBrushGC, None );
+ }
+ else
+ {
+ // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't always reflect
+ // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
+ if (mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
+ XSetFillStyle ( pDisplay, mpBrushGC, FillSolid );
+
+ XSetFillStyle ( pDisplay, mpBrushGC, FillTiled );
+ XSetTile ( pDisplay, mpBrushGC, mrParent.hBrush_ );
+ }
+ XSetFunction ( pDisplay, mpBrushGC, mbXORMode ? GXxor : GXcopy );
+ mrParent.SetClipRegion( mpBrushGC );
+
+ mbBrushGC = true;
+ }
+
+ return mpBrushGC;
+}
+
+GC X11SalGraphicsImpl::SelectPen()
+{
+ Display *pDisplay = mrParent.GetXDisplay();
+
+ if( !mpPenGC )
+ {
+ XGCValues values;
+ values.subwindow_mode = ClipByChildren;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = False;
+
+ mpPenGC = XCreateGC( pDisplay, mrParent.hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !mbPenGC )
+ {
+ if( mnPenColor != SALCOLOR_NONE )
+ XSetForeground( pDisplay, mpPenGC, mnPenPixel );
+ XSetFunction ( pDisplay, mpPenGC, mbXORMode ? GXxor : GXcopy );
+ mrParent.SetClipRegion( mpPenGC );
+ mbPenGC = true;
+ }
+
+ return mpPenGC;
+}
+
+void X11SalGraphicsImpl::DrawLines( sal_uLong nPoints,
+ const SalPolyLine &rPoints,
+ GC pGC,
+ bool bClose
+ )
+{
+ // calculate how many lines XWindow can draw in one go
+ sal_uLong nMaxLines = (mrParent.GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
+ / sizeof(xPoint);
+ if( nMaxLines > nPoints ) nMaxLines = nPoints;
+
+ // print all lines that XWindows can draw
+ sal_uLong n;
+ for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
+ XDrawLines( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nMaxLines,
+ CoordModeOrigin );
+
+ if( n < nPoints )
+ XDrawLines( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nPoints - n,
+ CoordModeOrigin );
+ if( bClose )
+ {
+ if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
+ drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
+ }
+}
+
+void X11SalGraphicsImpl::copyBits( const SalTwoRect& rPosAry,
+ SalGraphics *pSSrcGraphics )
+{
+ X11SalGraphics* pSrcGraphics = pSSrcGraphics
+ ? static_cast<X11SalGraphics*>(pSSrcGraphics)
+ : &mrParent;
+
+ if( rPosAry.mnSrcWidth <= 0
+ || rPosAry.mnSrcHeight <= 0
+ || rPosAry.mnDestWidth <= 0
+ || rPosAry.mnDestHeight <= 0 )
+ {
+ return;
+ }
+
+ int n;
+ if( pSrcGraphics == &mrParent )
+ {
+ n = 2;
+ }
+ else if( pSrcGraphics->bWindow_ )
+ {
+ // window or compatible virtual device
+ if( pSrcGraphics->GetDisplay() == mrParent.GetDisplay() &&
+ pSrcGraphics->m_nXScreen == mrParent.m_nXScreen &&
+ pSrcGraphics->GetVisual().GetDepth() == mrParent.GetVisual().GetDepth()
+ )
+ n = 2; // same Display
+ else
+ n = 1; // printer or other display
+ }
+ else if( pSrcGraphics->bVirDev_ )
+ {
+ // printer compatible virtual device
+ if( mrParent.bPrinter_ )
+ n = 2; // printer or compatible virtual device == same display
+ else
+ n = 1; // window or compatible virtual device
+ }
+ else
+ n = 0;
+
+ if( n == 2
+ && rPosAry.mnSrcWidth == rPosAry.mnDestWidth
+ && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
+ )
+ {
+ // #i60699# Need to generate graphics exposures (to repaint
+ // obscured areas beneath overlapping windows), src and dest
+ // are the same window.
+ const bool bNeedGraphicsExposures( pSrcGraphics == &mrParent &&
+ !mrParent.bVirDev_ &&
+ pSrcGraphics->bWindow_ );
+
+ GC pCopyGC;
+
+ if( mbXORMode
+ && !pSrcGraphics->bVirDev_
+ && (mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
+ {
+ Pixmap hPixmap = limitXCreatePixmap( mrParent.GetXDisplay(),
+ pSrcGraphics->GetDrawable(), // source
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+ pSrcGraphics->GetBitCount() );
+
+ pCopyGC = mrParent.GetDisplay()->GetCopyGC( mrParent.m_nXScreen );
+
+ if( bNeedGraphicsExposures )
+ XSetGraphicsExposures( mrParent.GetXDisplay(),
+ pCopyGC,
+ True );
+
+ XCopyArea( mrParent.GetXDisplay(),
+ pSrcGraphics->GetDrawable(), // source
+ hPixmap, // destination
+ pCopyGC, // no clipping
+ rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+ 0, 0 ); // destination
+ XCopyArea( mrParent.GetXDisplay(),
+ hPixmap, // source
+ mrParent.GetDrawable(), // destination
+ GetInvertGC(), // destination clipping
+ 0, 0, // source
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+ rPosAry.mnDestX, rPosAry.mnDestY );
+ XFreePixmap( mrParent.GetXDisplay(), hPixmap );
+ }
+ else
+ {
+ pCopyGC = GetCopyGC();
+
+ if( bNeedGraphicsExposures )
+ XSetGraphicsExposures( mrParent.GetXDisplay(),
+ pCopyGC,
+ True );
+
+ XCopyArea( mrParent.GetXDisplay(),
+ pSrcGraphics->GetDrawable(), // source
+ mrParent.GetDrawable(), // destination
+ pCopyGC, // destination clipping
+ rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+ rPosAry.mnDestX, rPosAry.mnDestY );
+ }
+
+ if( bNeedGraphicsExposures )
+ {
+ mrParent.YieldGraphicsExpose();
+
+ if( pCopyGC )
+ XSetGraphicsExposures( mrParent.GetXDisplay(),
+ pCopyGC,
+ False );
+ }
+ }
+ else if( n )
+ {
+ // #i60699# No chance to handle graphics exposures - we copy
+ // to a temp bitmap first, into which no repaints are
+ // technically possible.
+ boost::scoped_ptr<SalBitmap> pDDB(pSrcGraphics->getBitmap( rPosAry.mnSrcX,
+ rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth,
+ rPosAry.mnSrcHeight ));
+
+ if( !pDDB )
+ {
+ stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
+ return;
+ }
+
+ SalTwoRect aPosAry( rPosAry );
+
+ aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0;
+ drawBitmap( aPosAry, *pDDB );
+ }
+ else {
+ stderr0( "X11SalGraphicsImpl::CopyBits from Printer not yet implemented\n" );
+ }
+}
+
+void X11SalGraphicsImpl::copyArea ( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 )
+{
+ SalTwoRect aPosAry;
+
+ aPosAry.mnDestX = nDestX;
+ aPosAry.mnDestY = nDestY;
+ aPosAry.mnDestWidth = nSrcWidth;
+ aPosAry.mnDestHeight = nSrcHeight;
+
+ aPosAry.mnSrcX = nSrcX;
+ aPosAry.mnSrcY = nSrcY;
+ aPosAry.mnSrcWidth = nSrcWidth;
+ aPosAry.mnSrcHeight = nSrcHeight;
+
+ copyBits ( aPosAry, 0 );
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
+{
+ const SalDisplay* pSalDisp = mrParent.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ const Drawable aDrawable( mrParent.GetDrawable() );
+ const SalColormap& rColMap = pSalDisp->GetColormap( mrParent.m_nXScreen );
+ const long nDepth = mrParent.GetDisplay()->GetVisual( mrParent.m_nXScreen ).GetDepth();
+ GC aGC( GetCopyGC() );
+ XGCValues aOldVal, aNewVal;
+ int nValues = GCForeground | GCBackground;
+
+ if( rSalBitmap.GetBitCount() == 1 )
+ {
+ // set foreground/background values for 1Bit bitmaps
+ XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
+ setForeBack(aNewVal, rColMap, rSalBitmap);
+ XChangeGC( pXDisp, aGC, nValues, &aNewVal );
+ }
+
+ static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, mrParent.m_nXScreen, nDepth, rPosAry, aGC );
+
+ if( rSalBitmap.GetBitCount() == 1 )
+ XChangeGC( pXDisp, aGC, nValues, &aOldVal );
+ XFlush( pXDisp );
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry,
+ const SalBitmap& rSrcBitmap,
+ const SalBitmap& rMaskBitmap )
+{
+ DBG_ASSERT( !mrParent.bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
+
+ // decide if alpha masking or transparency masking is needed
+ BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( true );
+ if( pAlphaBuffer != NULL )
+ {
+ int nMaskFormat = pAlphaBuffer->mnFormat;
+ const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, true );
+ if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
+ drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
+ }
+
+ drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
+}
+
+void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransBitmap )
+{
+ const SalDisplay* pSalDisp = mrParent.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ Drawable aDrawable( mrParent.GetDrawable() );
+
+ // figure work mode depth. If this is a VDev Drawable, use its
+ // bitdepth to create pixmaps for, otherwise, XCopyArea will
+ // refuse to work.
+ const sal_uInt16 nDepth( mrParent.m_pVDev ?
+ mrParent.m_pVDev->GetDepth() :
+ pSalDisp->GetVisual( mrParent.m_nXScreen ).GetDepth() );
+ Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+ rPosAry.mnDestHeight, nDepth ) );
+ Pixmap aBG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+ rPosAry.mnDestHeight, nDepth ) );
+
+ if( aFG && aBG )
+ {
+ GC aTmpGC;
+ XGCValues aValues;
+ setForeBack(aValues, pSalDisp->GetColormap(mrParent.m_nXScreen), rSalBitmap);
+ const int nValues = GCFunction | GCForeground | GCBackground;
+ SalTwoRect aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
+
+ // draw paint bitmap in pixmap #1
+ aValues.function = GXcopy;
+ aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
+ static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aFG, mrParent.m_nXScreen, nDepth, aTmpRect, aTmpGC );
+ DBG_TESTTRANS( aFG );
+
+ // draw background in pixmap #2
+ XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
+ rPosAry.mnDestX, rPosAry.mnDestY,
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+ 0, 0 );
+
+ DBG_TESTTRANS( aBG );
+
+ // mask out paint bitmap in pixmap #1 (transparent areas 0)
+ aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aFG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
+
+ DBG_TESTTRANS( aFG );
+
+ // #105055# For XOR mode, keep background behind bitmap intact
+ if( !mbXORMode )
+ {
+ // mask out background in pixmap #2 (nontransparent areas 0)
+ aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aBG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
+
+ DBG_TESTTRANS( aBG );
+ }
+
+ // merge pixmap #1 and pixmap #2 in pixmap #2
+ aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+ XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+ XCopyArea( pXDisp, aFG, aBG, aTmpGC,
+ 0, 0,
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+ 0, 0 );
+ DBG_TESTTRANS( aBG );
+
+ // #105055# Disable XOR temporarily
+ bool bOldXORMode( mbXORMode );
+ mbXORMode = false;
+
+ // copy pixmap #2 (result) to background
+ XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
+ 0, 0,
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+ rPosAry.mnDestX, rPosAry.mnDestY );
+
+ DBG_TESTTRANS( aBG );
+
+ mbXORMode = bOldXORMode;
+
+ XFreeGC( pXDisp, aTmpGC );
+ XFlush( pXDisp );
+ }
+ else
+ drawBitmap( rPosAry, rSalBitmap );
+
+ if( aFG )
+ XFreePixmap( pXDisp, aFG );
+
+ if( aBG )
+ XFreePixmap( pXDisp, aBG );
+}
+
+bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
+ const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
+{
+ // non 8-bit alpha not implemented yet
+ if( rAlphaBmp.GetBitCount() != 8 )
+ return false;
+
+ // horizontal mirroring not implemented yet
+ if( rTR.mnDestWidth < 0 )
+ return false;
+
+ // stretched conversion is not implemented yet
+ if( rTR.mnDestWidth != rTR.mnSrcWidth )
+ return false;
+ if( rTR.mnDestHeight!= rTR.mnSrcHeight )
+ return false;
+
+ // create destination picture
+ Picture aDstPic = GetXRenderPicture();
+ if( !aDstPic )
+ return false;
+
+ const SalDisplay* pSalDisp = mrParent.GetDisplay();
+ const SalVisual& rSalVis = pSalDisp->GetVisual( mrParent.m_nXScreen );
+ Display* pXDisplay = pSalDisp->GetDisplay();
+
+ // create source Picture
+ int nDepth = mrParent.m_pVDev ? mrParent.m_pVDev->GetDepth() : rSalVis.GetDepth();
+ const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
+ ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR );
+ if( !pSrcDDB )
+ return false;
+
+ //#i75249# workaround for ImplGetDDB() giving us back a different depth than
+ // we requested. E.g. mask pixmaps are always compatible with the drawable
+ // TODO: find an appropriate picture format for these cases
+ // then remove the workaround below and the one for #i75531#
+ if( nDepth != pSrcDDB->ImplGetDepth() )
+ return false;
+
+ Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
+ if( !aSrcPM )
+ return false;
+
+ // create source picture
+ // TODO: use scoped picture
+ Visual* pSrcXVisual = rSalVis.GetVisual();
+ XRenderPeer& rPeer = XRenderPeer::GetInstance();
+ XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
+ if( !pSrcVisFmt )
+ return false;
+ Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
+ if( !aSrcPic )
+ return false;
+
+ // create alpha Picture
+
+ // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
+ // problem is that they don't provide an 8bit Pixmap on a non-8bit display
+ BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( true );
+
+ // an XImage needs its data top_down
+ // TODO: avoid wrongly oriented images in upper layers!
+ const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
+ const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
+ char* pAlphaBits = new char[ nImageSize ];
+ if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
+ memcpy( pAlphaBits, pSrcBits, nImageSize );
+ else
+ {
+ char* pDstBits = pAlphaBits + nImageSize;
+ const int nLineSize = pAlphaBuffer->mnScanlineSize;
+ for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
+ memcpy( pDstBits, pSrcBits, nLineSize );
+ }
+
+ // the alpha values need to be inverted for XRender
+ // TODO: make upper layers use standard alpha
+ long* pLDst = (long*)pAlphaBits;
+ for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
+ *pLDst = ~*pLDst;
+
+ char* pCDst = (char*)pLDst;
+ for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
+ *pCDst = ~*pCDst;
+
+ const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
+ XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
+ pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
+ pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
+
+ Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_,
+ rTR.mnDestWidth, rTR.mnDestHeight, 8 );
+
+ XGCValues aAlphaGCV;
+ aAlphaGCV.function = GXcopy;
+ GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
+ XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
+ rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
+ XFreeGC( pXDisplay, aAlphaGC );
+ XFree( pAlphaImg );
+ if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
+ delete[] pAlphaBits;
+
+ const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, true );
+
+ XRenderPictureAttributes aAttr;
+ aAttr.repeat = int(true);
+ Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
+ if( !aAlphaPic )
+ return false;
+
+ // set clipping
+ if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
+ rPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
+
+ // paint source * mask over destination picture
+ rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
+ rTR.mnSrcX, rTR.mnSrcY, 0, 0,
+ rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
+
+ rPeer.FreePicture( aAlphaPic );
+ XFreePixmap(pXDisplay, aAlphaPM);
+ rPeer.FreePicture( aSrcPic );
+ return true;
+}
+
+bool X11SalGraphicsImpl::drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap)
+{
+ // here direct support for transformed bitmaps can be impemented
+ (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+ return false;
+}
+
+bool X11SalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
+ long nHeight, sal_uInt8 nTransparency )
+{
+ if( ! mrParent.m_pFrame && ! mrParent.m_pVDev )
+ return false;
+
+ if( mbPenGC || !mbBrushGC || mbXORMode )
+ return false; // can only perform solid fills without XOR.
+
+ if( mrParent.m_pVDev && mrParent.m_pVDev->GetDepth() < 8 )
+ return false;
+
+ Picture aDstPic = GetXRenderPicture();
+ if( !aDstPic )
+ return false;
+
+ const double fTransparency = (100 - nTransparency) * (1.0/100);
+ const XRenderColor aRenderColor = GetXRenderColor( mnBrushColor , fTransparency);
+
+ XRenderPeer& rPeer = XRenderPeer::GetInstance();
+ rPeer.FillRectangle( PictOpOver,
+ aDstPic,
+ &aRenderColor,
+ nX, nY,
+ nWidth, nHeight );
+
+ return true;
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect&,
+ const SalBitmap&,
+ SalColor )
+{
+ OSL_FAIL( "::DrawBitmap with transparent color not supported" );
+}
+
+void X11SalGraphicsImpl::drawMask( const SalTwoRect& rPosAry,
+ const SalBitmap &rSalBitmap,
+ SalColor nMaskColor )
+{
+ const SalDisplay* pSalDisp = mrParent.GetDisplay();
+ Display* pXDisp = pSalDisp->GetDisplay();
+ Drawable aDrawable( mrParent.GetDrawable() );
+ Pixmap aStipple( limitXCreatePixmap( pXDisp, aDrawable,
+ rPosAry.mnDestWidth,
+ rPosAry.mnDestHeight, 1 ) );
+
+ if( aStipple )
+ {
+ SalTwoRect aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
+ GC aTmpGC;
+ XGCValues aValues;
+
+ // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
+ aValues.function = GXcopyInverted;
+ aValues.foreground = 1, aValues.background = 0;
+ aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
+ static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aStipple, mrParent.m_nXScreen, 1, aTwoRect, aTmpGC );
+
+ XFreeGC( pXDisp, aTmpGC );
+
+ // Set stipple and draw rectangle
+ GC aStippleGC( GetStippleGC() );
+ int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
+
+ XSetStipple( pXDisp, aStippleGC, aStipple );
+ XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
+ XSetForeground( pXDisp, aStippleGC, mrParent.GetPixel( nMaskColor ) );
+ XFillRectangle( pXDisp, aDrawable, aStippleGC,
+ nX, nY,
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight );
+ XFreePixmap( pXDisp, aStipple );
+ XFlush( pXDisp );
+ }
+ else
+ drawBitmap( rPosAry, rSalBitmap );
+}
+
+void X11SalGraphicsImpl::ResetClipRegion()
+{
+ if( mrParent.mpClipRegion )
+ {
+ mbPenGC = false;
+ mrParent.bFontGC_ = false;
+ mbBrushGC = false;
+ mbMonoGC = false;
+ mbCopyGC = false;
+ mbInvertGC = false;
+ mbInvert50GC = false;
+ mbStippleGC = false;
+ mbTrackingGC = false;
+
+ XDestroyRegion( mrParent.mpClipRegion );
+ mrParent.mpClipRegion = NULL;
+ }
+}
+
+bool X11SalGraphicsImpl::setClipRegion( const vcl::Region& i_rClip )
+{
+ if( mrParent.mpClipRegion )
+ XDestroyRegion( mrParent.mpClipRegion );
+ mrParent.mpClipRegion = XCreateRegion();
+
+ RectangleVector aRectangles;
+ i_rClip.GetRegionRectangles(aRectangles);
+
+ for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
+ {
+ const long nW(aRectIter->GetWidth());
+
+ if(nW)
+ {
+ const long nH(aRectIter->GetHeight());
+
+ if(nH)
+ {
+ XRectangle aRect;
+
+ aRect.x = (short)aRectIter->Left();
+ aRect.y = (short)aRectIter->Top();
+ aRect.width = (unsigned short)nW;
+ aRect.height = (unsigned short)nH;
+ XUnionRectWithRegion(&aRect, mrParent.mpClipRegion, mrParent.mpClipRegion);
+ }
+ }
+ }
+
+ //ImplRegionInfo aInfo;
+ //long nX, nY, nW, nH;
+ //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+ //while( bRegionRect )
+ //{
+ // if ( nW && nH )
+ // {
+ // XRectangle aRect;
+ // aRect.x = (short)nX;
+ // aRect.y = (short)nY;
+ // aRect.width = (unsigned short)nW;
+ // aRect.height = (unsigned short)nH;
+
+ // XUnionRectWithRegion( &aRect, mrParent.mpClipRegion, mrParent.mpClipRegion );
+ // }
+ // bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+ //}
+
+ // done, invalidate GCs
+ mbPenGC = false;
+ mrParent.bFontGC_ = false;
+ mbBrushGC = false;
+ mbMonoGC = false;
+ mbCopyGC = false;
+ mbInvertGC = false;
+ mbInvert50GC = false;
+ mbStippleGC = false;
+ mbTrackingGC = false;
+
+ if( XEmptyRegion( mrParent.mpClipRegion ) )
+ {
+ XDestroyRegion( mrParent.mpClipRegion );
+ mrParent.mpClipRegion= NULL;
+ }
+ return true;
+}
+
+void X11SalGraphicsImpl::SetLineColor()
+{
+ if( mnPenColor != SALCOLOR_NONE )
+ {
+ mnPenColor = SALCOLOR_NONE;
+ mbPenGC = false;
+ }
+}
+
+void X11SalGraphicsImpl::SetLineColor( SalColor nSalColor )
+{
+ if( mnPenColor != nSalColor )
+ {
+ mnPenColor = nSalColor;
+ mnPenPixel = mrParent.GetPixel( nSalColor );
+ mbPenGC = false;
+ }
+}
+
+void X11SalGraphicsImpl::SetFillColor()
+{
+ if( mnBrushColor != SALCOLOR_NONE )
+ {
+ mbDitherBrush = false;
+ mnBrushColor = SALCOLOR_NONE;
+ mbBrushGC = false;
+ }
+}
+
+void X11SalGraphicsImpl::SetFillColor( SalColor nSalColor )
+{
+ if( mnBrushColor != nSalColor )
+ {
+ mbDitherBrush = false;
+ mnBrushColor = nSalColor;
+ mnBrushPixel = mrParent.GetPixel( nSalColor );
+ if( TrueColor != mrParent.GetColormap().GetVisual().GetClass()
+ && mrParent.GetColormap().GetColor( mnBrushPixel ) != mnBrushColor
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
+ && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
+ mbDitherBrush = mrParent.GetDitherPixmap(nSalColor);
+ mbBrushGC = false;
+ }
+}
+
+void X11SalGraphicsImpl::SetROPLineColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ mnPenPixel = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ mnPenPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ mnPenPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+ break;
+ }
+ mnPenColor = mrParent.GetColormap().GetColor( mnPenPixel );
+ mbPenGC = false;
+}
+
+void X11SalGraphicsImpl::SetROPFillColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ mnBrushPixel = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ mnBrushPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ mnBrushPixel = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+ break;
+ }
+ mbDitherBrush = false;
+ mnBrushColor = mrParent.GetColormap().GetColor( mnBrushPixel );
+ mbBrushGC = false;
+}
+
+void X11SalGraphicsImpl::SetXORMode( bool bSet, bool )
+{
+ if( !mbXORMode == bSet )
+ {
+ mbXORMode = bSet;
+ mbPenGC = false;
+ mrParent.bFontGC_ = false;
+ mbBrushGC = false;
+ mbMonoGC = false;
+ mbCopyGC = false;
+ mbInvertGC = false;
+ mbInvert50GC = false;
+ mbStippleGC = false;
+ mbTrackingGC = false;
+ }
+}
+
+void X11SalGraphicsImpl::drawPixel( long nX, long nY )
+{
+ if( mnPenColor != SALCOLOR_NONE )
+ XDrawPoint( mrParent.GetXDisplay(), mrParent.GetDrawable(), SelectPen(), nX, nY );
+}
+
+void X11SalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ if( nSalColor != SALCOLOR_NONE )
+ {
+ Display *pDisplay = mrParent.GetXDisplay();
+
+ if( (mnPenColor == SALCOLOR_NONE) && !mbPenGC )
+ {
+ SetLineColor( nSalColor );
+ XDrawPoint( pDisplay, mrParent.GetDrawable(), SelectPen(), nX, nY );
+ mnPenColor = SALCOLOR_NONE;
+ mbPenGC = False;
+ }
+ else
+ {
+ GC pGC = SelectPen();
+
+ if( nSalColor != mnPenColor )
+ XSetForeground( pDisplay, pGC, mrParent.GetPixel( nSalColor ) );
+
+ XDrawPoint( pDisplay, mrParent.GetDrawable(), pGC, nX, nY );
+
+ if( nSalColor != mnPenColor )
+ XSetForeground( pDisplay, pGC, mnPenPixel );
+ }
+ }
+}
+
+void X11SalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( mnPenColor != SALCOLOR_NONE )
+ {
+ if ( mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
+ {
+ GC aGC = SelectPen();
+ XDrawPoint (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, (int)nX1, (int)nY1);
+ XDrawPoint (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, (int)nX2, (int)nY2);
+ XDrawLine (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
+ }
+ else
+ XDrawLine( mrParent.GetXDisplay(), mrParent.GetDrawable(),SelectPen(),
+ nX1, nY1, nX2, nY2 );
+ }
+}
+
+void X11SalGraphicsImpl::drawRect( long nX, long nY, long nDX, long nDY )
+{
+ if( mnBrushColor != SALCOLOR_NONE )
+ {
+ XFillRectangle( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ SelectBrush(),
+ nX, nY, nDX, nDY );
+ }
+ // description DrawRect is wrong; thus -1
+ if( mnPenColor != SALCOLOR_NONE )
+ XDrawRectangle( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ SelectPen(),
+ nX, nY, nDX-1, nDY-1 );
+}
+
+void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
+{
+ drawPolyLine( nPoints, pPtAry, false );
+}
+
+void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry, bool bClose )
+{
+ if( mnPenColor != SALCOLOR_NONE )
+ {
+ SalPolyLine Points( nPoints, pPtAry );
+
+ DrawLines( nPoints, Points, SelectPen(), bClose );
+ }
+}
+
+void X11SalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ if( nPoints == 0 )
+ return;
+
+ if( nPoints < 3 )
+ {
+ if( !mbXORMode )
+ {
+ if( 1 == nPoints )
+ drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ else
+ drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ }
+ return;
+ }
+
+ SalPolyLine Points( nPoints, pPtAry );
+
+ nPoints++;
+
+ /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
+ * do not draw the visible part of a polygon
+ * if it overlaps to the left of screen 0,y.
+ * This happens to be the case in the gradient drawn in the
+ * menubar background. workaround for the special case of
+ * of a rectangle overlapping to the left.
+ */
+ if( nPoints == 5 &&
+ Points[ 0 ].x == Points[ 1 ].x &&
+ Points[ 1 ].y == Points[ 2 ].y &&
+ Points[ 2 ].x == Points[ 3 ].x &&
+ Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
+ )
+ {
+ bool bLeft = false;
+ bool bRight = false;
+ for(unsigned int i = 0; i < nPoints; i++ )
+ {
+ if( Points[i].x < 0 )
+ bLeft = true;
+ else
+ bRight= true;
+ }
+ if( bLeft && ! bRight )
+ return;
+ if( bLeft && bRight )
+ {
+ for( unsigned int i = 0; i < nPoints; i++ )
+ if( Points[i].x < 0 )
+ Points[i].x = 0;
+ }
+ }
+
+ if( mnBrushColor != SALCOLOR_NONE )
+ XFillPolygon( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ SelectBrush(),
+ &Points[0], nPoints,
+ Complex, CoordModeOrigin );
+
+ if( mnPenColor != SALCOLOR_NONE )
+ DrawLines( nPoints, Points, SelectPen(), true );
+}
+
+void X11SalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly,
+ const sal_uInt32 *pPoints,
+ PCONSTSALPOINT *pPtAry )
+{
+ if( mnBrushColor != SALCOLOR_NONE )
+ {
+ sal_uInt32 i, n;
+ Region pXRegA = NULL;
+
+ for( i = 0; i < nPoly; i++ ) {
+ n = pPoints[i];
+ SalPolyLine Points( n, pPtAry[i] );
+ if( n > 2 )
+ {
+ Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
+ if( !pXRegA )
+ pXRegA = pXRegB;
+ else
+ {
+ XXorRegion( pXRegA, pXRegB, pXRegA );
+ XDestroyRegion( pXRegB );
+ }
+ }
+ }
+
+ if( pXRegA )
+ {
+ XRectangle aXRect;
+ XClipBox( pXRegA, &aXRect );
+
+ GC pGC = SelectBrush();
+ mrParent.SetClipRegion( pGC, pXRegA ); // ??? twice
+ XDestroyRegion( pXRegA );
+ mbBrushGC = false;
+
+ XFillRectangle( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ pGC,
+ aXRect.x, aXRect.y, aXRect.width, aXRect.height );
+ }
+ }
+
+ if( mnPenColor != SALCOLOR_NONE )
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ drawPolyLine( pPoints[i], pPtAry[i], true );
+}
+
+bool X11SalGraphicsImpl::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+{
+ return false;
+}
+
+bool X11SalGraphicsImpl::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+{
+ return false;
+}
+
+bool X11SalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
+ const SalPoint* const*, const sal_uInt8* const* )
+{
+ return false;
+}
+
+void X11SalGraphicsImpl::invert( long nX,
+ long nY,
+ long nDX,
+ long nDY,
+ SalInvert nFlags )
+{
+ GC pGC;
+ if( SAL_INVERT_50 & nFlags )
+ {
+ pGC = GetInvert50GC();
+ XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+ else
+ {
+ if ( SAL_INVERT_TRACKFRAME & nFlags )
+ {
+ pGC = GetTrackingGC();
+ XDrawRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+ else
+ {
+ pGC = GetInvertGC();
+ XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(), pGC, nX, nY, nDX, nDY );
+ }
+ }
+}
+
+void X11SalGraphicsImpl::invert( sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ SalInvert nFlags )
+{
+ SalPolyLine Points ( nPoints, pPtAry );
+
+ GC pGC;
+ if( SAL_INVERT_50 & nFlags )
+ pGC = GetInvert50GC();
+ else
+ if ( SAL_INVERT_TRACKFRAME & nFlags )
+ pGC = GetTrackingGC();
+ else
+ pGC = GetInvertGC();
+
+ if( SAL_INVERT_TRACKFRAME & nFlags )
+ DrawLines ( nPoints, Points, pGC, true );
+ else
+ XFillPolygon( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ pGC,
+ &Points[0], nPoints,
+ Complex, CoordModeOrigin );
+}
+
+bool X11SalGraphicsImpl::drawEPS( long,long,long,long,void*,sal_uLong )
+{
+ return false;
+}
+
+// draw a poly-polygon
+bool X11SalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency )
+{
+ // nothing to do for empty polypolygons
+ const int nOrigPolyCount = rOrigPolyPoly.count();
+ if( nOrigPolyCount <= 0 )
+ return true;
+
+ // nothing to do if everything is transparent
+ if( (mnBrushColor == SALCOLOR_NONE)
+ && (mnPenColor == SALCOLOR_NONE) )
+ return true;
+
+ // cannot handle pencolor!=brushcolor yet
+ if( (mnPenColor != SALCOLOR_NONE)
+ && (mnPenColor != mnBrushColor) )
+ return false;
+
+ // TODO: remove the env-variable when no longer needed
+ static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
+ if( pRenderEnv )
+ return false;
+
+ // snap to raster if requested
+ basegfx::B2DPolyPolygon aPolyPoly = rOrigPolyPoly;
+ const bool bSnapToRaster = !mrParent.getAntiAliasB2DDraw();
+ if( bSnapToRaster )
+ aPolyPoly = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges( aPolyPoly );
+
+ // don't bother with polygons outside of visible area
+ const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
+ aPolyPoly = basegfx::tools::clipPolyPolygonOnRange( aPolyPoly, aViewRange, true, false );
+ if( !aPolyPoly.count() )
+ return true;
+
+ // tesselate the polypolygon into trapezoids
+ basegfx::B2DTrapezoidVector aB2DTrapVector;
+ basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly );
+ const int nTrapCount = aB2DTrapVector.size();
+ if( !nTrapCount )
+ return true;
+ const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
+ return bDrawn;
+}
+
+long X11SalGraphicsImpl::GetGraphicsHeight() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nHeight;
+ else if( mrParent.m_pVDev )
+ return mrParent.m_pVDev->GetHeight();
+ else
+ return 0;
+}
+
+bool X11SalGraphicsImpl::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTraps, int nTrapCount, double fTransparency )
+{
+ if( nTrapCount <= 0 )
+ return true;
+
+ Picture aDstPic = GetXRenderPicture();
+ // check xrender support for this drawable
+ if( !aDstPic )
+ return false;
+
+ // convert the B2DTrapezoids into XRender-Trapezoids
+ typedef std::vector<XTrapezoid> TrapezoidVector;
+ TrapezoidVector aTrapVector( nTrapCount );
+ const basegfx::B2DTrapezoid* pB2DTrap = pB2DTraps;
+ for( int i = 0; i < nTrapCount; ++pB2DTrap, ++i )
+ {
+ XTrapezoid& rTrap = aTrapVector[ i ] ;
+
+ // set y-coordinates
+ const double fY1 = pB2DTrap->getTopY();
+ rTrap.left.p1.y = rTrap.right.p1.y = rTrap.top = XDoubleToFixed( fY1 );
+ const double fY2 = pB2DTrap->getBottomY();
+ rTrap.left.p2.y = rTrap.right.p2.y = rTrap.bottom = XDoubleToFixed( fY2 );
+
+ // set x-coordinates
+ const double fXL1 = pB2DTrap->getTopXLeft();
+ rTrap.left.p1.x = XDoubleToFixed( fXL1 );
+ const double fXR1 = pB2DTrap->getTopXRight();
+ rTrap.right.p1.x = XDoubleToFixed( fXR1 );
+ const double fXL2 = pB2DTrap->getBottomXLeft();
+ rTrap.left.p2.x = XDoubleToFixed( fXL2 );
+ const double fXR2 = pB2DTrap->getBottomXRight();
+ rTrap.right.p2.x = XDoubleToFixed( fXR2 );
+ }
+
+ // get xrender Picture for polygon foreground
+ // TODO: cache it like the target picture which uses GetXRenderPicture()
+ XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+ SalDisplay::RenderEntry& rEntry = mrParent.GetDisplay()->GetRenderEntries( mrParent.m_nXScreen )[ 32 ];
+ if( !rEntry.m_aPicture )
+ {
+ Display* pXDisplay = mrParent.GetXDisplay();
+
+ rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, 1, 1, 32 );
+ XRenderPictureAttributes aAttr;
+ aAttr.repeat = int(true);
+
+ XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
+ rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
+ }
+
+ // set polygon foreground color and opacity
+ XRenderColor aRenderColor = GetXRenderColor( mnBrushColor , fTransparency );
+ rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
+
+ // set clipping
+ // TODO: move into GetXRenderPicture?
+ if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
+ rRenderPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
+
+ // render the trapezoids
+ const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
+ rRenderPeer.CompositeTrapezoids( PictOpOver,
+ rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
+
+ return true;
+}
+
+bool X11SalGraphicsImpl::drawPolyLine(
+ const ::basegfx::B2DPolygon& rPolygon,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidth,
+ basegfx::B2DLineJoin eLineJoin,
+ com::sun::star::drawing::LineCap eLineCap)
+{
+ const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2);
+
+ // #i101491#
+ if( !bIsHairline && (rPolygon.count() > 1000) )
+ {
+ // the used basegfx::tools::createAreaGeometry is simply too
+ // expensive with very big polygons; fallback to caller (who
+ // should use ImplLineConverter normally)
+ // AW: ImplLineConverter had to be removed since it does not even
+ // know LineJoins, so the fallback will now prepare the line geometry
+ // the same way.
+ return false;
+ }
+
+ // temporarily adjust brush color to pen color
+ // since the line is drawn as an area-polygon
+ const SalColor aKeepBrushColor = mnBrushColor;
+ mnBrushColor = mnPenColor;
+
+ // #i11575#desc5#b adjust B2D tesselation result to raster positions
+ basegfx::B2DPolygon aPolygon = rPolygon;
+ const double fHalfWidth = 0.5 * rLineWidth.getX();
+
+ // #i122456# This is probably thought to happen to align hairlines to pixel positions, so
+ // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines
+ aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) );
+
+ // shortcut for hairline drawing to improve performance
+ 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 );
+
+ // restore the original brush GC
+ mnBrushColor = aKeepBrushColor;
+ return bDrawnOk;
+ }
+
+ // get the area polygon for the line polygon
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
+ {
+ // prepare for createAreaGeometry() with anisotropic linewidth
+ aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
+ }
+
+ // create the area-polygon for the line
+ const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) );
+
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
+ {
+ // postprocess createAreaGeometry() for anisotropic linewidth
+ aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
+ }
+
+ // draw each area polypolygon component individually
+ // to emulate the polypolygon winding rule "non-zero"
+ const int nPolyCount = aAreaPolyPoly.count();
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
+ bDrawnOk = drawPolyPolygon( aOnePoly, fTransparency );
+ if( !bDrawnOk )
+ break;
+ }
+
+ // restore the original brush GC
+ mnBrushColor = aKeepBrushColor;
+ return bDrawnOk;
+}
+
+SalColor X11SalGraphicsImpl::getPixel( long nX, long nY )
+{
+ if( mrParent.bWindow_ && !mrParent.bVirDev_ )
+ {
+ XWindowAttributes aAttrib;
+
+ XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
+ if( aAttrib.map_state != IsViewable )
+ {
+ stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
+ return 0;
+ }
+ }
+
+ XImage *pXImage = XGetImage( mrParent.GetXDisplay(),
+ mrParent.GetDrawable(),
+ nX, nY,
+ 1, 1,
+ AllPlanes,
+ ZPixmap );
+ if( !pXImage )
+ {
+ stderr0( "X11SalGraphics::GetPixel !XGetImage()\n" );
+ return 0;
+ }
+
+ XColor aXColor;
+
+ aXColor.pixel = XGetPixel( pXImage, 0, 0 );
+ XDestroyImage( pXImage );
+
+ return mrParent.GetColormap().GetColor( aXColor.pixel );
+}
+
+SalBitmap *X11SalGraphicsImpl::getBitmap( long nX, long nY, long nDX, long nDY )
+{
+ if( mrParent.bPrinter_ && !mrParent.bVirDev_ )
+ return NULL;
+
+ bool bFakeWindowBG = false;
+
+ // normalize
+ if( nDX < 0 )
+ {
+ nX += nDX;
+ nDX = -nDX;
+ }
+ if ( nDY < 0 )
+ {
+ nY += nDY;
+ nDY = -nDY;
+ }
+
+ if( mrParent.bWindow_ && !mrParent.bVirDev_ )
+ {
+ XWindowAttributes aAttrib;
+
+ XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
+ if( aAttrib.map_state != IsViewable )
+ bFakeWindowBG = true;
+ else
+ {
+ long nOrgDX = nDX, nOrgDY = nDY;
+
+ // clip to window size
+ if ( nX < 0 )
+ {
+ nDX += nX;
+ nX = 0;
+ }
+ if ( nY < 0 )
+ {
+ nDY += nY;
+ nY = 0;
+ }
+ if( nX + nDX > aAttrib.width )
+ nDX = aAttrib.width - nX;
+ if( nY + nDY > aAttrib.height )
+ nDY = aAttrib.height - nY;
+
+ // inside ?
+ if( nDX <= 0 || nDY <= 0 )
+ {
+ bFakeWindowBG = true;
+ nDX = nOrgDX;
+ nDY = nOrgDY;
+ }
+ }
+ }
+
+ X11SalBitmap* pSalBitmap = new X11SalBitmap;
+ sal_uInt16 nBitCount = GetBitCount();
+
+ if( &mrParent.GetDisplay()->GetColormap( mrParent.m_nXScreen ) != &mrParent.GetColormap() )
+ nBitCount = 1;
+
+ if( ! bFakeWindowBG )
+ pSalBitmap->ImplCreateFromDrawable( mrParent.GetDrawable(), mrParent.m_nXScreen, nBitCount, nX, nY, nDX, nDY );
+ else
+ pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
+
+ return pSalBitmap;
+}
+
+sal_uInt16 X11SalGraphicsImpl::GetBitCount() const
+{
+ return mrParent.GetVisual().GetDepth();
+}
+
+long X11SalGraphicsImpl::GetGraphicsWidth() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nWidth;
+ else if( mrParent.m_pVDev )
+ return mrParent.m_pVDev->GetWidth();
+ else
+ return 0;
+}
+
+bool X11SalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/, const Gradient& /*rGradient*/)
+{
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
new file mode 100644
index 000000000000..252fe358f505
--- /dev/null
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -0,0 +1,278 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCULDED_VCL_GENERIC_GDI_GDIIMPL_HXX
+#define INCLUDED_VCL_GENERIC_GDI_GDIIMPL_HXX
+
+#include <prex.h>
+#include <postx.h>
+
+#include "unx/saltype.h"
+#include "unx/x11/x11gdiimpl.h"
+
+#include "salgdiimpl.hxx"
+
+#include <basegfx/polygon/b2dtrapezoid.hxx>
+
+class SalGraphics;
+class SalBitmap;
+class SalPolyLine;
+class X11SalGraphics;
+class Gradient;
+
+class X11SalGraphicsImpl : public SalGraphicsImpl, public X11GraphicsImpl
+{
+private:
+ X11SalGraphics& mrParent;
+
+ SalColor mnBrushColor;
+ GC mpBrushGC; // Brush attributes
+ Pixel mnBrushPixel;
+
+ bool mbPenGC : 1; // is Pen GC valid
+ bool mbBrushGC : 1; // is Brush GC valid
+ bool mbMonoGC : 1; // is Mono GC valid
+ bool mbCopyGC : 1; // is Copy GC valid
+ bool mbInvertGC : 1; // is Invert GC valid
+ bool mbInvert50GC : 1; // is Invert50 GC valid
+ bool mbStippleGC : 1; // is Stipple GC valid
+ bool mbTrackingGC : 1; // is Tracking GC valid
+ bool mbDitherBrush : 1; // is solid or tile
+
+ bool mbXORMode : 1; // is ROP XOR Mode set
+
+ GC mpPenGC; // Pen attributes
+ SalColor mnPenColor;
+ Pixel mnPenPixel;
+
+
+ GC mpMonoGC;
+ GC mpCopyGC;
+ GC mpMaskGC;
+ GC mpInvertGC;
+ GC mpInvert50GC;
+ GC mpStippleGC;
+ GC mpTrackingGC;
+
+ GC CreateGC( Drawable hDrawable,
+ unsigned long nMask = GCGraphicsExposures );
+
+ GC SelectBrush();
+ GC SelectPen();
+ inline GC GetCopyGC();
+ inline GC GetStippleGC();
+ GC GetTrackingGC();
+ GC GetInvertGC();
+ GC GetInvert50GC();
+ inline GC GetMonoGC( Pixmap hPixmap );
+
+ void DrawLines( sal_uIntPtr nPoints,
+ const SalPolyLine &rPoints,
+ GC pGC,
+ bool bClose
+ );
+
+ XID GetXRenderPicture();
+ bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
+
+ long GetGraphicsHeight() const;
+
+ void drawMaskedBitmap( const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransparentBitmap );
+
+ void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+
+public:
+
+ X11SalGraphicsImpl(X11SalGraphics& rParent);
+
+ virtual void freeResources() SAL_OVERRIDE;
+
+ virtual ~X11SalGraphicsImpl();
+
+ virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
+ //
+ // get the depth of the device
+ virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+ // get the width of the device
+ virtual long GetGraphicsWidth() const SAL_OVERRIDE;
+
+ // set the clip region to empty
+ virtual void ResetClipRegion() SAL_OVERRIDE;
+
+ // set the line color to transparent (= don't draw lines)
+
+ virtual void SetLineColor() SAL_OVERRIDE;
+
+ // set the line color to a specific color
+ virtual void SetLineColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // set the fill color to transparent (= don't fill)
+ virtual void SetFillColor() SAL_OVERRIDE;
+
+ // set the fill color to a specific color, shapes will be
+ // filled accordingly
+ virtual void SetFillColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // enable/disable XOR drawing
+ virtual void SetXORMode( bool bSet, bool bInvertOnly ) SAL_OVERRIDE;
+
+ // set line color for raster operations
+ virtual void SetROPLineColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // set fill color for raster operations
+ virtual void SetROPFillColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // draw --> LineColor and FillColor and RasterOp and ClipRegion
+ virtual void drawPixel( long nX, long nY ) SAL_OVERRIDE;
+ virtual void drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
+
+ virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
+
+ virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) SAL_OVERRIDE;
+ virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) SAL_OVERRIDE;
+
+ virtual bool drawPolyLine(
+ const ::basegfx::B2DPolygon&,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin,
+ com::sun::star::drawing::LineCap) SAL_OVERRIDE;
+
+ virtual bool drawPolyLineBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolygonBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolyPolygonBezier(
+ sal_uInt32 nPoly,
+ const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry,
+ const sal_uInt8* const* pFlgAry ) SAL_OVERRIDE;
+
+ // CopyArea --> No RasterOp, but ClipRegion
+ virtual void copyArea(
+ long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 nFlags ) SAL_OVERRIDE;
+
+ // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+ // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+ virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
+
+ virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap ) SAL_OVERRIDE;
+
+ virtual void drawMask(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor ) SAL_OVERRIDE;
+
+ virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual SalColor getPixel( long nX, long nY ) SAL_OVERRIDE;
+
+ // invert --> ClipRegion (only Windows or VirDevs)
+ virtual void invert(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags) SAL_OVERRIDE;
+
+ virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) SAL_OVERRIDE;
+
+ virtual bool drawEPS(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ void* pPtr,
+ sal_uLong nSize ) SAL_OVERRIDE;
+
+ /** Render bitmap with alpha channel
+
+ @param rSourceBitmap
+ Source bitmap to blit
+
+ @param rAlphaBitmap
+ Alpha channel to use for blitting
+
+ @return true, if the operation succeeded, and false
+ otherwise. In this case, clients should try to emulate alpha
+ compositing themselves
+ */
+ virtual bool drawAlphaBitmap(
+ const SalTwoRect&,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
+ /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+ virtual bool drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap) SAL_OVERRIDE;
+
+ /** Render solid rectangle with given transparency
+
+ @param nTransparency
+ Transparency value (0-255) to use. 0 blits and opaque, 255 a
+ fully transparent rectangle
+ */
+ virtual bool drawAlphaRect(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency ) SAL_OVERRIDE;
+
+ virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) SAL_OVERRIDE;
+
+ virtual bool swapBuffers() SAL_OVERRIDE { return false; }
+
+public:
+ // implementation of X11GraphicsImpl
+
+ void Init() SAL_OVERRIDE;
+ X11Pixmap* GetPixmapFromScreen( const Rectangle& rRect ) SAL_OVERRIDE;
+ bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.cxx b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx
new file mode 100644
index 000000000000..9b7c49ed450f
--- /dev/null
+++ b/vcl/unx/generic/gdi/openglx11cairotextrender.cxx
@@ -0,0 +1,50 @@
+/* -*- 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/.
+ */
+
+#include "openglx11cairotextrender.hxx"
+
+#include "salbmp.hxx"
+#include <vcl/salbtype.hxx>
+
+#include <cairo-svg.h>
+
+OpenGLX11CairoTextRender::OpenGLX11CairoTextRender(bool bPrinter, X11SalGraphics& rParent):
+ X11CairoTextRender(bPrinter, rParent)
+{
+}
+
+cairo_surface_t* OpenGLX11CairoTextRender::getCairoSurface()
+{
+ // static size_t id = 0;
+ // OString aFileName = OString("/tmp/libo_logs/text_rendering") + OString::number(id++) + OString(".svg");
+ // cairo_surface_t* surface = cairo_svg_surface_create(aFileName.getStr(), GetWidth(), GetHeight());
+ cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, GetWidth(), GetHeight());
+ return surface;
+}
+
+void OpenGLX11CairoTextRender::drawSurface(cairo_t* cr)
+{
+ cairo_surface_t* surface = cairo_get_target(cr);
+ int width = cairo_image_surface_get_width(surface);
+ int height = cairo_image_surface_get_height(surface);
+ SalBitmap* pBitmap = ImplGetSVData()->mpDefInst->CreateSalBitmap();
+ pBitmap->Create(Size(width, height), 24, BitmapPalette());
+ BitmapBuffer* pBuffer = pBitmap->AcquireBuffer(false);
+ std::memcpy(pBuffer->mpBits, cairo_image_surface_get_data(surface), width*height*3);
+ pBitmap->ReleaseBuffer(pBuffer, false);
+ SalTwoRect aRect;
+ aRect.mnSrcX = 0;
+ aRect.mnSrcY = 0;
+ aRect.mnSrcWidth = width;
+ aRect.mnSrcHeight = height;
+ mrParent.drawBitmap(aRect, *pBitmap);
+ delete pBitmap;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/openglx11cairotextrender.hxx b/vcl/unx/generic/gdi/openglx11cairotextrender.hxx
new file mode 100644
index 000000000000..87ef9483cacb
--- /dev/null
+++ b/vcl/unx/generic/gdi/openglx11cairotextrender.hxx
@@ -0,0 +1,26 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_UNX_GENERIC_GDI_OPENGLX11CAIROTEXTRENDER_HXX
+#define INCLUDED_VCL_UNX_GENERIC_GDI_OPENGLX11CAIROTEXTRENDER_HXX value
+
+#include "x11cairotextrender.hxx"
+
+class OpenGLX11CairoTextRender : public X11CairoTextRender
+{
+public:
+ OpenGLX11CairoTextRender(bool bPrinter, X11SalGraphics& rParent);
+
+ virtual cairo_surface_t* getCairoSurface() SAL_OVERRIDE;
+ virtual void drawSurface(cairo_t* cr) SAL_OVERRIDE;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/pixmap.cxx b/vcl/unx/generic/gdi/pixmap.cxx
new file mode 100644
index 000000000000..beb5589e2425
--- /dev/null
+++ b/vcl/unx/generic/gdi/pixmap.cxx
@@ -0,0 +1,49 @@
+/* -*- 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/.
+ */
+
+#include "unx/pixmap.hxx"
+
+X11Pixmap::X11Pixmap()
+: mpDisplay( NULL )
+, mnScreen( 0 )
+, mnWidth( -1 )
+, mnHeight( -1 )
+, mnDepth( 0 )
+{
+}
+
+X11Pixmap::X11Pixmap( Display* pDisplay, SalX11Screen nScreen, int nWidth, int nHeight, int nDepth )
+: mpDisplay( pDisplay )
+, mnScreen( nScreen )
+, mnWidth( nWidth )
+, mnHeight( nHeight )
+, mnDepth( nDepth )
+{
+ Window root = RootWindow( pDisplay, 0 );
+ mpPixmap = XCreatePixmap( pDisplay, root, nWidth, nHeight, nDepth );
+}
+
+X11Pixmap::X11Pixmap( X11Pixmap& rOther )
+: mpDisplay( rOther.mpDisplay )
+, mnScreen( rOther.mnScreen )
+, mnWidth( rOther.mnWidth )
+, mnHeight( rOther.mnHeight )
+, mnDepth( rOther.mnDepth )
+{
+ mpPixmap = rOther.mpPixmap;
+ rOther.mpPixmap = 0;
+}
+
+X11Pixmap::~X11Pixmap()
+{
+ if( mpPixmap )
+ XFreePixmap( mpDisplay, mpPixmap );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx
index e68078e7c919..6b2042c842c4 100644
--- a/vcl/unx/generic/gdi/salbmp.cxx
+++ b/vcl/unx/generic/gdi/salbmp.cxx
@@ -43,6 +43,10 @@
#include <unx/salinst.h>
#include <unx/x11/xlimits.hxx>
+#include <opengl/salbmp.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include <officecfg/Office/Common.hxx>
+
#if defined HAVE_VALGRIND_HEADERS
#include <valgrind/memcheck.h>
#endif
@@ -53,7 +57,12 @@
SalBitmap* X11SalInstance::CreateSalBitmap()
{
- return new X11SalBitmap();
+ static bool bOpenGLPossible = OpenGLHelper::supportsVCLOpenGL();
+ bool bUseOpenGL = bOpenGLPossible ? officecfg::Office::Common::VCL::UseOpenGL::get() : false;
+ if (bUseOpenGL)
+ return new OpenGLSalBitmap();
+ else
+ return new X11SalBitmap();
}
ImplSalBitmapCache* X11SalBitmap::mpCache = NULL;
@@ -854,6 +863,11 @@ bool X11SalBitmap::GetSystemData( BitmapSystemData& rData )
return false;
}
+bool X11SalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, sal_uInt32 /*nScaleFlag*/ )
+{
+ return false;
+}
+
// - ImplSalDDB -
ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable,
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 4441458578b0..47b20bc84d82 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -48,101 +48,55 @@
#include "unx/salgdi.h"
#include "unx/salframe.h"
#include "unx/salvd.h"
+#include "unx/x11/x11gdiimpl.h"
#include <unx/x11/xlimits.hxx>
+#include "salgdiimpl.hxx"
+#include "unx/x11windowprovider.hxx"
+#include "textrender.hxx"
+#include "gdiimpl.hxx"
+#include "opengl/x11/gdiimpl.hxx"
+#include "x11cairotextrender.hxx"
+#include "openglx11cairotextrender.hxx"
+
#include "generic/printergfx.hxx"
#include "xrender_peer.hxx"
-#define STATIC_POINTS 64
-
-class SalPolyLine
-{
- XPoint Points_[STATIC_POINTS];
- XPoint *pFirst_;
-public:
- SalPolyLine(sal_uLong nPoints, const SalPoint *p)
- : pFirst_(nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_)
- {
- for( sal_uLong i = 0; i < nPoints; i++ )
- {
- pFirst_[i].x = (short)p[i].mnX;
- pFirst_[i].y = (short)p[i].mnY;
- }
- pFirst_[nPoints] = pFirst_[0]; // close polyline
+#include <officecfg/Office/Common.hxx>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+X11SalGraphics::X11SalGraphics():
+ m_pFrame(NULL),
+ m_pVDev(NULL),
+ m_pColormap(NULL),
+ m_pDeleteColormap(NULL),
+ hDrawable_(None),
+ m_nXScreen( 0 ),
+ m_pXRenderFormat(NULL),
+ m_aXRenderPicture(0),
+ pPaintRegion_(NULL),
+ mpClipRegion(NULL),
+ pFontGC_(NULL),
+ nTextPixel_(0),
+ hBrush_(None),
+ bWindow_(false),
+ bPrinter_(false),
+ bVirDev_(false)
+{
+ static bool bOpenGLPossible = OpenGLHelper::supportsVCLOpenGL();
+ bool bUseOpenGL = bOpenGLPossible ? officecfg::Office::Common::VCL::UseOpenGL::get() : false;
+ if (bUseOpenGL)
+ {
+ mpImpl.reset(new X11OpenGLSalGraphicsImpl(*this));
+ mpTextRenderImpl.reset((new OpenGLX11CairoTextRender(false, *this)));
}
-
- ~SalPolyLine()
- {
- if( pFirst_ != Points_ )
- delete [] pFirst_;
- }
-
- XPoint &operator [] ( sal_uLong n ) const
+ else
{
- return pFirst_[n];
+ mpTextRenderImpl.reset((new X11CairoTextRender(false, *this)));
+ mpImpl.reset(new X11SalGraphicsImpl(*this));
}
-};
-
-#undef STATIC_POINTS
-X11SalGraphics::X11SalGraphics()
- : m_nXScreen( 0 )
-{
- m_pFrame = NULL;
- m_pVDev = NULL;
- m_pColormap = NULL;
- m_pDeleteColormap = NULL;
- hDrawable_ = None;
- m_aXRenderPicture = 0;
- m_pXRenderFormat = NULL;
-
- mpClipRegion = NULL;
- pPaintRegion_ = NULL;
-
- pPenGC_ = NULL;
- nPenPixel_ = 0;
- nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
- pFontGC_ = NULL;
- for( int i = 0; i < MAX_FALLBACK; ++i )
- mpServerFont[i] = NULL;
-
- nTextPixel_ = 0;
- nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
-#if ENABLE_GRAPHITE
- // check if graphite fonts have been disabled
- static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" );
- bDisableGraphite_ = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
-#endif
-
- pBrushGC_ = NULL;
- nBrushPixel_ = 0;
- nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
- hBrush_ = None;
-
- pMonoGC_ = NULL;
- pCopyGC_ = NULL;
- pMaskGC_ = NULL;
- pInvertGC_ = NULL;
- pInvert50GC_ = NULL;
- pStippleGC_ = NULL;
- pTrackingGC_ = NULL;
-
- bWindow_ = false;
- bPrinter_ = false;
- bVirDev_ = false;
- bPenGC_ = false;
- bFontGC_ = false;
- bBrushGC_ = false;
- bMonoGC_ = false;
- bCopyGC_ = false;
- bInvertGC_ = false;
- bInvert50GC_ = false;
- bStippleGC_ = false;
- bTrackingGC_ = false;
- bXORMode_ = false;
- bDitherBrush_ = false;
}
X11SalGraphics::~X11SalGraphics()
@@ -158,24 +112,17 @@ void X11SalGraphics::freeResources()
DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" );
if( mpClipRegion ) XDestroyRegion( mpClipRegion ), mpClipRegion = None;
+ mpImpl->freeResources();
+
if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None;
- if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
- if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
- if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
- if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
- if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
- if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
- if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
- if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
- if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
- if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
+ if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
if( m_pDeleteColormap )
delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL;
if( m_aXRenderPicture )
XRenderPeer::GetInstance().FreePicture( m_aXRenderPicture ), m_aXRenderPicture = 0;
- bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false;
+ bFontGC_ = false;
}
void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
@@ -202,9 +149,8 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
if( hDrawable_ )
{
- nPenPixel_ = GetPixel( nPenColor_ );
- nTextPixel_ = GetPixel( nTextColor_ );
- nBrushPixel_ = GetPixel( nBrushColor_ );
+ dynamic_cast<X11GraphicsImpl*>(mpImpl.get())->Init();
+ // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
}
}
@@ -213,10 +159,10 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
{
m_pColormap = &GetGenericData()->GetSalDisplay()->GetColormap(nXScreen);
m_nXScreen = nXScreen;
+ m_pFrame = pFrame;
SetDrawable( aTarget, nXScreen );
bWindow_ = true;
- m_pFrame = pFrame;
m_pVDev = NULL;
}
@@ -252,146 +198,6 @@ void X11SalGraphics::SetClipRegion( GC pGC, Region pXReg ) const
}
}
-GC X11SalGraphics::SelectPen()
-{
- Display *pDisplay = GetXDisplay();
-
- if( !pPenGC_ )
- {
- XGCValues values;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pPenGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bPenGC_ )
- {
- if( nPenColor_ != SALCOLOR_NONE )
- XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
- XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pPenGC_ );
- bPenGC_ = true;
- }
-
- return pPenGC_;
-}
-
-GC X11SalGraphics::SelectBrush()
-{
- Display *pDisplay = GetXDisplay();
-
- DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
-
- if( !pBrushGC_ )
- {
- XGCValues values;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bBrushGC_ )
- {
- if( !bDitherBrush_ )
- {
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
- XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
- if( bPrinter_ )
- XSetTile( pDisplay, pBrushGC_, None );
- }
- else
- {
- // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't always reflect
- // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
- if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
-
- XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
- XSetTile ( pDisplay, pBrushGC_, hBrush_ );
- }
- XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pBrushGC_ );
-
- bBrushGC_ = true;
- }
-
- return pBrushGC_;
-}
-
-GC X11SalGraphics::GetTrackingGC()
-{
- const char dash_list[2] = {2, 2};
-
- if( !pTrackingGC_ )
- {
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetBlackPixel()
- ^ m_pColormap->GetWhitePixel();
- values.function = GXxor;
- values.line_width = 1;
- values.line_style = LineOnOffDash;
-
- pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
- GCGraphicsExposures | GCForeground | GCFunction
- | GCLineWidth | GCLineStyle,
- &values );
- XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
- }
-
- if( !bTrackingGC_ )
- {
- SetClipRegion( pTrackingGC_ );
- bTrackingGC_ = true;
- }
-
- return pTrackingGC_;
-}
-
-void X11SalGraphics::DrawLines( sal_uLong nPoints,
- const SalPolyLine &rPoints,
- GC pGC,
- bool bClose
- )
-{
- // calculate how many lines XWindow can draw in one go
- sal_uLong nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
- / sizeof(xPoint);
- if( nMaxLines > nPoints ) nMaxLines = nPoints;
-
- // print all lines that XWindows can draw
- sal_uLong n;
- for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nMaxLines,
- CoordModeOrigin );
-
- if( n < nPoints )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nPoints - n,
- CoordModeOrigin );
- if( bClose )
- {
- if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
- drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
- }
-}
-
// Calculate a dither-pixmap and make a brush of it
#define P_DELTA 51
#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
@@ -506,493 +312,123 @@ void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // cons
sal_uInt16 X11SalGraphics::GetBitCount() const
{
- return GetVisual().GetDepth();
+ return mpImpl->GetBitCount();
}
long X11SalGraphics::GetGraphicsWidth() const
{
- if( m_pFrame )
- return m_pFrame->maGeometry.nWidth;
- else if( m_pVDev )
- return m_pVDev->GetWidth();
- else
- return 0;
-}
-
-long X11SalGraphics::GetGraphicsHeight() const
-{
- if( m_pFrame )
- return m_pFrame->maGeometry.nHeight;
- else if( m_pVDev )
- return m_pVDev->GetHeight();
- else
- return 0;
+ return mpImpl->GetGraphicsWidth();
}
void X11SalGraphics::ResetClipRegion()
{
- if( mpClipRegion )
- {
- bPenGC_ = false;
- bFontGC_ = false;
- bBrushGC_ = false;
- bMonoGC_ = false;
- bCopyGC_ = false;
- bInvertGC_ = false;
- bInvert50GC_ = false;
- bStippleGC_ = false;
- bTrackingGC_ = false;
-
- XDestroyRegion( mpClipRegion );
- mpClipRegion = NULL;
- }
+ mpImpl->ResetClipRegion();
}
bool X11SalGraphics::setClipRegion( const vcl::Region& i_rClip )
{
- if( mpClipRegion )
- XDestroyRegion( mpClipRegion );
- mpClipRegion = XCreateRegion();
-
- RectangleVector aRectangles;
- i_rClip.GetRegionRectangles(aRectangles);
-
- for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
- {
- const long nW(aRectIter->GetWidth());
-
- if(nW)
- {
- const long nH(aRectIter->GetHeight());
-
- if(nH)
- {
- XRectangle aRect;
-
- aRect.x = (short)aRectIter->Left();
- aRect.y = (short)aRectIter->Top();
- aRect.width = (unsigned short)nW;
- aRect.height = (unsigned short)nH;
- XUnionRectWithRegion(&aRect, mpClipRegion, mpClipRegion);
- }
- }
- }
-
- //ImplRegionInfo aInfo;
- //long nX, nY, nW, nH;
- //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
- //while( bRegionRect )
- //{
- // if ( nW && nH )
- // {
- // XRectangle aRect;
- // aRect.x = (short)nX;
- // aRect.y = (short)nY;
- // aRect.width = (unsigned short)nW;
- // aRect.height = (unsigned short)nH;
-
- // XUnionRectWithRegion( &aRect, mpClipRegion, mpClipRegion );
- // }
- // bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
- //}
-
- // done, invalidate GCs
- bPenGC_ = false;
- bFontGC_ = false;
- bBrushGC_ = false;
- bMonoGC_ = false;
- bCopyGC_ = false;
- bInvertGC_ = false;
- bInvert50GC_ = false;
- bStippleGC_ = false;
- bTrackingGC_ = false;
-
- if( XEmptyRegion( mpClipRegion ) )
- {
- XDestroyRegion( mpClipRegion );
- mpClipRegion= NULL;
- }
- return true;
+ return mpImpl->setClipRegion( i_rClip );
}
void X11SalGraphics::SetLineColor()
{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = false;
- }
+ mpImpl->SetLineColor();
}
void X11SalGraphics::SetLineColor( SalColor nSalColor )
{
- if( nPenColor_ != nSalColor )
- {
- nPenColor_ = nSalColor;
- nPenPixel_ = GetPixel( nSalColor );
- bPenGC_ = false;
- }
+ mpImpl->SetLineColor( nSalColor );
}
void X11SalGraphics::SetFillColor()
{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- bDitherBrush_ = false;
- nBrushColor_ = SALCOLOR_NONE;
- bBrushGC_ = false;
- }
+ mpImpl->SetFillColor();
}
void X11SalGraphics::SetFillColor( SalColor nSalColor )
{
- if( nBrushColor_ != nSalColor )
- {
- bDitherBrush_ = false;
- nBrushColor_ = nSalColor;
- nBrushPixel_ = GetPixel( nSalColor );
- if( TrueColor != GetColormap().GetVisual().GetClass()
- && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
- && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
- bDitherBrush_ = GetDitherPixmap(nSalColor);
- bBrushGC_ = false;
- }
+ mpImpl->SetFillColor( nSalColor );
}
void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor )
{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nPenPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- nPenColor_ = GetColormap().GetColor( nPenPixel_ );
- bPenGC_ = false;
+ mpImpl->SetROPLineColor( nROPColor );
}
void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor )
{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nBrushPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- bDitherBrush_ = false;
- nBrushColor_ = GetColormap().GetColor( nBrushPixel_ );
- bBrushGC_ = false;
+ mpImpl->SetROPFillColor( nROPColor );
}
-void X11SalGraphics::SetXORMode( bool bSet, bool )
+void X11SalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
{
- if( !bXORMode_ == bSet )
- {
- bXORMode_ = bSet;
- bPenGC_ = false;
- bFontGC_ = false;
- bBrushGC_ = false;
- bMonoGC_ = false;
- bCopyGC_ = false;
- bInvertGC_ = false;
- bInvert50GC_ = false;
- bStippleGC_ = false;
- bTrackingGC_ = false;
- }
+ mpImpl->SetXORMode( bSet, bInvertOnly );
}
void X11SalGraphics::drawPixel( long nX, long nY )
{
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY );
+ mpImpl->drawPixel( nX, nY );
}
void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
{
- if( nSalColor != SALCOLOR_NONE )
- {
- Display *pDisplay = GetXDisplay();
-
- if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
- {
- SetLineColor( nSalColor );
- XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY );
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = False;
- }
- else
- {
- GC pGC = SelectPen();
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) );
-
- XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY );
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, nPenPixel_ );
- }
- }
+ mpImpl->drawPixel( nX, nY, nSalColor );
}
void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
- {
- GC aGC = SelectPen();
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1);
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2);
- XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
- }
- else
- XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(),
- nX1, nY1, nX2, nY2 );
- }
+ mpImpl->drawLine( nX1, nY1, nX2, nY2 );
}
void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY )
{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- nX, nY, nDX, nDY );
- }
- // description DrawRect is wrong; thus -1
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawRectangle( GetXDisplay(),
- GetDrawable(),
- SelectPen(),
- nX, nY, nDX-1, nDY-1 );
+ mpImpl->drawRect( nX, nY, nDX, nDY );
}
void X11SalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
{
- drawPolyLine( nPoints, pPtAry, false );
-}
-
-void X11SalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry, bool bClose )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- SalPolyLine Points( nPoints, pPtAry );
-
- DrawLines( nPoints, Points, SelectPen(), bClose );
- }
+ mpImpl->drawPolyLine( nPoints, pPtAry );
}
void X11SalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- if( nPoints == 0 )
- return;
-
- if( nPoints < 3 )
- {
- if( !bXORMode_ )
- {
- if( 1 == nPoints )
- drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
- else
- drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
- pPtAry[1].mnX, pPtAry[1].mnY );
- }
- return;
- }
-
- SalPolyLine Points( nPoints, pPtAry );
-
- nPoints++;
-
- /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
- * do not draw the visible part of a polygon
- * if it overlaps to the left of screen 0,y.
- * This happens to be the case in the gradient drawn in the
- * menubar background. workaround for the special case of
- * of a rectangle overlapping to the left.
- */
- if( nPoints == 5 &&
- Points[ 0 ].x == Points[ 1 ].x &&
- Points[ 1 ].y == Points[ 2 ].y &&
- Points[ 2 ].x == Points[ 3 ].x &&
- Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
- )
- {
- bool bLeft = false;
- bool bRight = false;
- for(unsigned int i = 0; i < nPoints; i++ )
- {
- if( Points[i].x < 0 )
- bLeft = true;
- else
- bRight= true;
- }
- if( bLeft && ! bRight )
- return;
- if( bLeft && bRight )
- {
- for( unsigned int i = 0; i < nPoints; i++ )
- if( Points[i].x < 0 )
- Points[i].x = 0;
- }
- }
-
- if( nBrushColor_ != SALCOLOR_NONE )
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-
- if( nPenColor_ != SALCOLOR_NONE )
- DrawLines( nPoints, Points, SelectPen(), true );
+ mpImpl->drawPolygon( nPoints, pPtAry );
}
void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
const sal_uInt32 *pPoints,
PCONSTSALPOINT *pPtAry )
{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- sal_uInt32 i, n;
- Region pXRegA = NULL;
-
- for( i = 0; i < nPoly; i++ ) {
- n = pPoints[i];
- SalPolyLine Points( n, pPtAry[i] );
- if( n > 2 )
- {
- Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
- if( !pXRegA )
- pXRegA = pXRegB;
- else
- {
- XXorRegion( pXRegA, pXRegB, pXRegA );
- XDestroyRegion( pXRegB );
- }
- }
- }
-
- if( pXRegA )
- {
- XRectangle aXRect;
- XClipBox( pXRegA, &aXRect );
-
- GC pGC = SelectBrush();
- SetClipRegion( pGC, pXRegA ); // ??? twice
- XDestroyRegion( pXRegA );
- bBrushGC_ = false;
-
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- pGC,
- aXRect.x, aXRect.y, aXRect.width, aXRect.height );
- }
- }
-
- if( nPenColor_ != SALCOLOR_NONE )
- for( sal_uInt32 i = 0; i < nPoly; i++ )
- drawPolyLine( pPoints[i], pPtAry[i], true );
+ mpImpl->drawPolyPolygon( nPoly, pPoints, pPtAry );
}
-bool X11SalGraphics::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+bool X11SalGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
{
- return false;
+ return mpImpl->drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
}
-bool X11SalGraphics::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+bool X11SalGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
{
- return false;
+ return mpImpl->drawPolygonBezier( nPoints, pPtAry, pFlgAry );
}
-bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
- const SalPoint* const*, const sal_uInt8* const* )
+bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoints, const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry)
{
- return false;
+ return mpImpl->drawPolyPolygonBezier( nPoints, pPoints, pPtAry, pFlgAry );
}
void X11SalGraphics::invert( sal_uInt32 nPoints,
const SalPoint* pPtAry,
SalInvert nFlags )
{
- SalPolyLine Points ( nPoints, pPtAry );
-
- GC pGC;
- if( SAL_INVERT_50 & nFlags )
- pGC = GetInvert50GC();
- else
- if ( SAL_INVERT_TRACKFRAME & nFlags )
- pGC = GetTrackingGC();
- else
- pGC = GetInvertGC();
-
- if( SAL_INVERT_TRACKFRAME & nFlags )
- DrawLines ( nPoints, Points, pGC, true );
- else
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- pGC,
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-}
-
-bool X11SalGraphics::drawEPS( long,long,long,long,void*,sal_uLong )
-{
- return false;
+ mpImpl->invert( nPoints, pPtAry, nFlags );
}
-XID X11SalGraphics::GetXRenderPicture()
+bool X11SalGraphics::drawEPS( long nX, long nY, long nWidth,
+ long nHeight, void* pPtr, sal_uLong nSize )
{
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
-
- if( !m_aXRenderPicture )
- {
- // check xrender support for matching visual
- XRenderPictFormat* pXRenderFormat = GetXRenderFormat();
- if( !pXRenderFormat )
- return 0;
- // get the matching xrender target for drawable
- m_aXRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pXRenderFormat, 0, NULL );
- }
-
- {
- // reset clip region
- // TODO: avoid clip reset if already done
- XRenderPictureAttributes aAttr;
- aAttr.clip_mask = None;
- rRenderPeer.ChangePicture( m_aXRenderPicture, CPClipMask, &aAttr );
- }
-
- return m_aXRenderPicture;
+ return mpImpl->drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize );
}
XRenderPictFormat* X11SalGraphics::GetXRenderFormat() const
@@ -1020,114 +456,7 @@ SystemGraphicsData X11SalGraphics::GetGraphicsData() const
// draw a poly-polygon
bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency )
{
- // nothing to do for empty polypolygons
- const int nOrigPolyCount = rOrigPolyPoly.count();
- if( nOrigPolyCount <= 0 )
- return true;
-
- // nothing to do if everything is transparent
- if( (nBrushColor_ == SALCOLOR_NONE)
- && (nPenColor_ == SALCOLOR_NONE) )
- return true;
-
- // cannot handle pencolor!=brushcolor yet
- if( (nPenColor_ != SALCOLOR_NONE)
- && (nPenColor_ != nBrushColor_) )
- return false;
-
- // TODO: remove the env-variable when no longer needed
- static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
- if( pRenderEnv )
- return false;
-
- // snap to raster if requested
- basegfx::B2DPolyPolygon aPolyPoly = rOrigPolyPoly;
- const bool bSnapToRaster = !getAntiAliasB2DDraw();
- if( bSnapToRaster )
- aPolyPoly = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges( aPolyPoly );
-
- // don't bother with polygons outside of visible area
- const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
- aPolyPoly = basegfx::tools::clipPolyPolygonOnRange( aPolyPoly, aViewRange, true, false );
- if( !aPolyPoly.count() )
- return true;
-
- // tesselate the polypolygon into trapezoids
- basegfx::B2DTrapezoidVector aB2DTrapVector;
- basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly );
- const int nTrapCount = aB2DTrapVector.size();
- if( !nTrapCount )
- return true;
- const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
- return bDrawn;
-}
-
-bool X11SalGraphics::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTraps, int nTrapCount, double fTransparency )
-{
- if( nTrapCount <= 0 )
- return true;
-
- Picture aDstPic = GetXRenderPicture();
- // check xrender support for this drawable
- if( !aDstPic )
- return false;
-
- // convert the B2DTrapezoids into XRender-Trapezoids
- typedef std::vector<XTrapezoid> TrapezoidVector;
- TrapezoidVector aTrapVector( nTrapCount );
- const basegfx::B2DTrapezoid* pB2DTrap = pB2DTraps;
- for( int i = 0; i < nTrapCount; ++pB2DTrap, ++i )
- {
- XTrapezoid& rTrap = aTrapVector[ i ] ;
-
- // set y-coordinates
- const double fY1 = pB2DTrap->getTopY();
- rTrap.left.p1.y = rTrap.right.p1.y = rTrap.top = XDoubleToFixed( fY1 );
- const double fY2 = pB2DTrap->getBottomY();
- rTrap.left.p2.y = rTrap.right.p2.y = rTrap.bottom = XDoubleToFixed( fY2 );
-
- // set x-coordinates
- const double fXL1 = pB2DTrap->getTopXLeft();
- rTrap.left.p1.x = XDoubleToFixed( fXL1 );
- const double fXR1 = pB2DTrap->getTopXRight();
- rTrap.right.p1.x = XDoubleToFixed( fXR1 );
- const double fXL2 = pB2DTrap->getBottomXLeft();
- rTrap.left.p2.x = XDoubleToFixed( fXL2 );
- const double fXR2 = pB2DTrap->getBottomXRight();
- rTrap.right.p2.x = XDoubleToFixed( fXR2 );
- }
-
- // get xrender Picture for polygon foreground
- // TODO: cache it like the target picture which uses GetXRenderPicture()
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nXScreen )[ 32 ];
- if( !rEntry.m_aPicture )
- {
- Display* pXDisplay = GetXDisplay();
-
- rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 );
- XRenderPictureAttributes aAttr;
- aAttr.repeat = int(true);
-
- XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
- rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
- }
-
- // set polygon foreground color and opacity
- XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency );
- rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
-
- // set clipping
- // TODO: move into GetXRenderPicture?
- if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, mpClipRegion );
-
- // render the trapezoids
- const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
- rRenderPeer.CompositeTrapezoids( PictOpOver,
- rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
-
- return true;
+ return mpImpl->drawPolyPolygon( rOrigPolyPoly, fTransparency );
}
bool X11SalGraphics::drawPolyLine(
@@ -1137,84 +466,18 @@ bool X11SalGraphics::drawPolyLine(
basegfx::B2DLineJoin eLineJoin,
com::sun::star::drawing::LineCap eLineCap)
{
- const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2);
-
- // #i101491#
- if( !bIsHairline && (rPolygon.count() > 1000) )
- {
- // the used basegfx::tools::createAreaGeometry is simply too
- // expensive with very big polygons; fallback to caller (who
- // should use ImplLineConverter normally)
- // AW: ImplLineConverter had to be removed since it does not even
- // know LineJoins, so the fallback will now prepare the line geometry
- // the same way.
- return false;
- }
-
- // temporarily adjust brush color to pen color
- // since the line is drawn as an area-polygon
- const SalColor aKeepBrushColor = nBrushColor_;
- nBrushColor_ = nPenColor_;
-
- // #i11575#desc5#b adjust B2D tesselation result to raster positions
- basegfx::B2DPolygon aPolygon = rPolygon;
- const double fHalfWidth = 0.5 * rLineWidth.getX();
-
- // #i122456# This is probably thought to happen to align hairlines to pixel positions, so
- // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines
- aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) );
-
- // shortcut for hairline drawing to improve performance
- 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 );
-
- // restore the original brush GC
- nBrushColor_ = aKeepBrushColor;
- return bDrawnOk;
- }
-
- // get the area polygon for the line polygon
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
- {
- // prepare for createAreaGeometry() with anisotropic linewidth
- aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
- }
-
- // create the area-polygon for the line
- const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) );
-
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
- {
- // postprocess createAreaGeometry() for anisotropic linewidth
- aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
- }
+ return mpImpl->drawPolyLine( rPolygon, fTransparency, rLineWidth,
+ eLineJoin, eLineCap );
+}
- // draw each area polypolygon component individually
- // to emulate the polypolygon winding rule "non-zero"
- const int nPolyCount = aAreaPolyPoly.count();
- for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
- {
- const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
- bDrawnOk = drawPolyPolygon( aOnePoly, fTransparency );
- if( !bDrawnOk )
- break;
- }
+bool X11SalGraphics::drawGradient(const tools::PolyPolygon& rPoly, const Gradient& rGradient)
+{
+ return mpImpl->drawGradient(rPoly, rGradient);
+}
- // restore the original brush GC
- nBrushColor_ = aKeepBrushColor;
- return bDrawnOk;
+bool X11SalGraphics::SwapBuffers()
+{
+ return mpImpl->swapBuffers();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 8059449c1371..63ab32b8981d 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -19,9 +19,11 @@
#include <stdio.h>
#include <poll.h>
+#include "salgdiimpl.hxx"
#include "vcl/salbtype.hxx"
+#include "unx/pixmap.hxx"
#include "unx/salunx.h"
#include "unx/saldata.hxx"
#include "unx/saldisp.hxx"
@@ -29,6 +31,7 @@
#include "unx/salgdi.h"
#include "unx/salframe.h"
#include "unx/salvd.h"
+#include "unx/x11/x11gdiimpl.h"
#include <unx/x11/xlimits.hxx>
#include "xrender_peer.hxx"
@@ -38,20 +41,6 @@
#include <outdata.hxx>
#include <boost/scoped_ptr.hpp>
-#undef SALGDI2_TESTTRANS
-
-#if (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
-#define DBG_TESTTRANS( _def_drawable ) \
-{ \
- XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(), \
- 0, 0, \
- rPosAry.mnDestWidth, rPosAry.mnDestHeight, \
- 0, 0 ); \
-}
-#else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
-#define DBG_TESTTRANS( _def_drawable )
-#endif // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
-
void X11SalGraphics::CopyScreenArea( Display* pDisplay,
Drawable aSrc, SalX11Screen nXScreenSrc, int nSrcDepth,
Drawable aDest, SalX11Screen nXScreenDest, int nDestDepth,
@@ -94,131 +83,17 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay,
}
}
-GC X11SalGraphics::CreateGC( Drawable hDrawable, unsigned long nMask )
-{
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetBlackPixel()
- ^ m_pColormap->GetWhitePixel();
- values.function = GXxor;
- values.line_width = 1;
- values.fill_style = FillStippled;
- values.stipple = GetDisplay()->GetInvert50( m_nXScreen );
- values.subwindow_mode = ClipByChildren;
-
- return XCreateGC( GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
-}
-
-inline GC X11SalGraphics::GetMonoGC( Pixmap hPixmap )
-{
- if( !pMonoGC_ )
- pMonoGC_ = CreateGC( hPixmap );
-
- if( !bMonoGC_ )
- {
- SetClipRegion( pMonoGC_ );
- bMonoGC_ = true;
- }
-
- return pMonoGC_;
-}
-
-inline GC X11SalGraphics::GetCopyGC()
+X11Pixmap* X11SalGraphics::GetPixmapFromScreen( const Rectangle& rRect )
{
- if( bXORMode_ ) return GetInvertGC();
-
- if( !pCopyGC_ )
- pCopyGC_ = CreateGC( GetDrawable() );
-
- if( !bCopyGC_ )
- {
- SetClipRegion( pCopyGC_ );
- bCopyGC_ = true;
- }
- return pCopyGC_;
+ X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get());
+ return pImpl->GetPixmapFromScreen( rRect );
}
-GC X11SalGraphics::GetInvertGC()
+bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY )
{
- if( !pInvertGC_ )
- pInvertGC_ = CreateGC( GetDrawable(),
- GCGraphicsExposures
- | GCForeground
- | GCFunction
- | GCLineWidth );
-
- if( !bInvertGC_ )
- {
- SetClipRegion( pInvertGC_ );
- bInvertGC_ = true;
- }
- return pInvertGC_;
-}
-
-GC X11SalGraphics::GetInvert50GC()
-{
- if( !pInvert50GC_ )
- {
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetWhitePixel();
- values.background = m_pColormap->GetBlackPixel();
- values.function = GXinvert;
- values.line_width = 1;
- values.line_style = LineSolid;
- unsigned long nValueMask =
- GCGraphicsExposures
- | GCForeground
- | GCBackground
- | GCFunction
- | GCLineWidth
- | GCLineStyle
- | GCFillStyle
- | GCStipple;
-
- char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
- if( pEnv && ! strcasecmp( pEnv, "true" ) )
- {
- values.fill_style = FillSolid;
- nValueMask &= ~ GCStipple;
- }
- else
- {
- values.fill_style = FillStippled;
- values.stipple = GetDisplay()->GetInvert50( m_nXScreen );
- }
-
- pInvert50GC_ = XCreateGC( GetXDisplay(), GetDrawable(),
- nValueMask,
- &values );
- }
-
- if( !bInvert50GC_ )
- {
- SetClipRegion( pInvert50GC_ );
- bInvert50GC_ = true;
- }
- return pInvert50GC_;
-}
-
-inline GC X11SalGraphics::GetStippleGC()
-{
- if( !pStippleGC_ )
- pStippleGC_ = CreateGC( GetDrawable(),
- GCGraphicsExposures
- | GCFillStyle
- | GCLineWidth );
-
- if( !bStippleGC_ )
- {
- XSetFunction( GetXDisplay(), pStippleGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pStippleGC_ );
- bStippleGC_ = true;
- }
-
- return pStippleGC_;
+ SAL_INFO( "vcl", "RenderPixmapToScreen" );
+ X11GraphicsImpl* pImpl = dynamic_cast<X11GraphicsImpl*>(mpImpl.get());
+ return pImpl->RenderPixmapToScreen( pPixmap, nX, nY );
}
extern "C"
@@ -281,456 +156,33 @@ void X11SalGraphics::YieldGraphicsExpose()
void X11SalGraphics::copyBits( const SalTwoRect& rPosAry,
SalGraphics *pSSrcGraphics )
{
- X11SalGraphics* pSrcGraphics = pSSrcGraphics
- ? static_cast<X11SalGraphics*>(pSSrcGraphics)
- : this;
-
- if( rPosAry.mnSrcWidth <= 0
- || rPosAry.mnSrcHeight <= 0
- || rPosAry.mnDestWidth <= 0
- || rPosAry.mnDestHeight <= 0 )
- {
- return;
- }
-
- int n;
- if( pSrcGraphics == this )
- {
- n = 2;
- }
- else if( pSrcGraphics->bWindow_ )
- {
- // window or compatible virtual device
- if( pSrcGraphics->GetDisplay() == GetDisplay() &&
- pSrcGraphics->m_nXScreen == m_nXScreen &&
- pSrcGraphics->GetVisual().GetDepth() == GetVisual().GetDepth()
- )
- n = 2; // same Display
- else
- n = 1; // printer or other display
- }
- else if( pSrcGraphics->bVirDev_ )
- {
- // printer compatible virtual device
- if( bPrinter_ )
- n = 2; // printer or compatible virtual device == same display
- else
- n = 1; // window or compatible virtual device
- }
- else
- n = 0;
-
- if( n == 2
- && rPosAry.mnSrcWidth == rPosAry.mnDestWidth
- && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
- )
- {
- // #i60699# Need to generate graphics exposures (to repaint
- // obscured areas beneath overlapping windows), src and dest
- // are the same window.
- const bool bNeedGraphicsExposures( pSrcGraphics == this &&
- !bVirDev_ &&
- pSrcGraphics->bWindow_ );
-
- GC pCopyGC;
-
- if( bXORMode_
- && !pSrcGraphics->bVirDev_
- && (GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
- {
- Pixmap hPixmap = limitXCreatePixmap( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- pSrcGraphics->GetBitCount() );
-
- pCopyGC = GetDisplay()->GetCopyGC( m_nXScreen );
-
- if( bNeedGraphicsExposures )
- XSetGraphicsExposures( GetXDisplay(),
- pCopyGC,
- True );
-
- XCopyArea( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- hPixmap, // destination
- pCopyGC, // no clipping
- rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- 0, 0 ); // destination
- XCopyArea( GetXDisplay(),
- hPixmap, // source
- GetDrawable(), // destination
- GetInvertGC(), // destination clipping
- 0, 0, // source
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- rPosAry.mnDestX, rPosAry.mnDestY );
- XFreePixmap( GetXDisplay(), hPixmap );
- }
- else
- {
- pCopyGC = GetCopyGC();
-
- if( bNeedGraphicsExposures )
- XSetGraphicsExposures( GetXDisplay(),
- pCopyGC,
- True );
-
- XCopyArea( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- GetDrawable(), // destination
- pCopyGC, // destination clipping
- rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- rPosAry.mnDestX, rPosAry.mnDestY );
- }
-
- if( bNeedGraphicsExposures )
- {
- YieldGraphicsExpose();
-
- if( pCopyGC )
- XSetGraphicsExposures( GetXDisplay(),
- pCopyGC,
- False );
- }
- }
- else if( n )
- {
- // #i60699# No chance to handle graphics exposures - we copy
- // to a temp bitmap first, into which no repaints are
- // technically possible.
- boost::scoped_ptr<SalBitmap> pDDB(pSrcGraphics->getBitmap( rPosAry.mnSrcX,
- rPosAry.mnSrcY,
- rPosAry.mnSrcWidth,
- rPosAry.mnSrcHeight ));
-
- if( !pDDB )
- {
- stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
- return;
- }
-
- SalTwoRect aPosAry( rPosAry );
-
- aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0;
- drawBitmap( aPosAry, *pDDB );
- }
- else {
- stderr0( "X11SalGraphics::CopyBits from Printer not yet implemented\n" );
- }
+ mpImpl->copyBits( rPosAry, pSSrcGraphics );
}
void X11SalGraphics::copyArea ( long nDestX, long nDestY,
long nSrcX, long nSrcY,
long nSrcWidth, long nSrcHeight,
- sal_uInt16 )
+ sal_uInt16 n )
{
- SalTwoRect aPosAry;
-
- aPosAry.mnDestX = nDestX;
- aPosAry.mnDestY = nDestY;
- aPosAry.mnDestWidth = nSrcWidth;
- aPosAry.mnDestHeight = nSrcHeight;
-
- aPosAry.mnSrcX = nSrcX;
- aPosAry.mnSrcY = nSrcY;
- aPosAry.mnSrcWidth = nSrcWidth;
- aPosAry.mnSrcHeight = nSrcHeight;
-
- copyBits ( aPosAry, 0 );
-}
-
-namespace
-{
- void setForeBack(XGCValues& rValues, const SalColormap& rColMap, const SalBitmap& rSalBitmap)
- {
- rValues.foreground = rColMap.GetWhitePixel();
- rValues.background = rColMap.GetBlackPixel();
-
- //fdo#33455 and fdo#80160 handle 1 bit depth pngs with palette entries
- //to set fore/back colors
- SalBitmap& rBitmap = const_cast<SalBitmap&>(rSalBitmap);
- if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(true))
- {
- const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
- if (rPalette.GetEntryCount() == 2)
- {
- const BitmapColor aWhite(rPalette[rPalette.GetBestIndex(Color(COL_WHITE))]);
- rValues.foreground = rColMap.GetPixel(ImplColorToSal(aWhite));
-
- const BitmapColor aBlack(rPalette[rPalette.GetBestIndex(Color(COL_BLACK))]);
- rValues.background = rColMap.GetPixel(ImplColorToSal(aBlack));
- }
- rBitmap.ReleaseBuffer(pBitmapBuffer, true);
- }
- }
+ mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, n );
}
void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- const Drawable aDrawable( GetDrawable() );
- const SalColormap& rColMap = pSalDisp->GetColormap( m_nXScreen );
- const long nDepth = GetDisplay()->GetVisual( m_nXScreen ).GetDepth();
- GC aGC( GetCopyGC() );
- XGCValues aOldVal, aNewVal;
- int nValues = GCForeground | GCBackground;
-
- if( rSalBitmap.GetBitCount() == 1 )
- {
- // set foreground/background values for 1Bit bitmaps
- XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
- setForeBack(aNewVal, rColMap, rSalBitmap);
- XChangeGC( pXDisp, aGC, nValues, &aNewVal );
- }
-
- static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nXScreen, nDepth, rPosAry, aGC );
-
- if( rSalBitmap.GetBitCount() == 1 )
- XChangeGC( pXDisp, aGC, nValues, &aOldVal );
- XFlush( pXDisp );
+ mpImpl->drawBitmap( rPosAry, rSalBitmap );
}
void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSrcBitmap,
const SalBitmap& rMaskBitmap )
{
- DBG_ASSERT( !bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
-
- // decide if alpha masking or transparency masking is needed
- BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( true );
- if( pAlphaBuffer != NULL )
- {
- int nMaskFormat = pAlphaBuffer->mnFormat;
- const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, true );
- if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
- drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
- }
-
- drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
-}
-
-void X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry,
- const SalBitmap& rSalBitmap,
- const SalBitmap& rTransBitmap )
-{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- Drawable aDrawable( GetDrawable() );
-
- // figure work mode depth. If this is a VDev Drawable, use its
- // bitdepth to create pixmaps for, otherwise, XCopyArea will
- // refuse to work.
- const sal_uInt16 nDepth( m_pVDev ?
- m_pVDev->GetDepth() :
- pSalDisp->GetVisual( m_nXScreen ).GetDepth() );
- Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
- rPosAry.mnDestHeight, nDepth ) );
- Pixmap aBG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
- rPosAry.mnDestHeight, nDepth ) );
-
- if( aFG && aBG )
- {
- GC aTmpGC;
- XGCValues aValues;
- setForeBack(aValues, pSalDisp->GetColormap(m_nXScreen), rSalBitmap);
- const int nValues = GCFunction | GCForeground | GCBackground;
- SalTwoRect aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
-
- // draw paint bitmap in pixmap #1
- aValues.function = GXcopy;
- aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
- static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aFG, m_nXScreen, nDepth, aTmpRect, aTmpGC );
- DBG_TESTTRANS( aFG );
-
- // draw background in pixmap #2
- XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
- rPosAry.mnDestX, rPosAry.mnDestY,
- rPosAry.mnDestWidth, rPosAry.mnDestHeight,
- 0, 0 );
-
- DBG_TESTTRANS( aBG );
-
- // mask out paint bitmap in pixmap #1 (transparent areas 0)
- aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
- XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
- static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aFG, m_nXScreen, 1, aTmpRect, aTmpGC );
-
- DBG_TESTTRANS( aFG );
-
- // #105055# For XOR mode, keep background behind bitmap intact
- if( !bXORMode_ )
- {
- // mask out background in pixmap #2 (nontransparent areas 0)
- aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
- XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
- static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aBG, m_nXScreen, 1, aTmpRect, aTmpGC );
-
- DBG_TESTTRANS( aBG );
- }
-
- // merge pixmap #1 and pixmap #2 in pixmap #2
- aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
- XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
- XCopyArea( pXDisp, aFG, aBG, aTmpGC,
- 0, 0,
- rPosAry.mnDestWidth, rPosAry.mnDestHeight,
- 0, 0 );
- DBG_TESTTRANS( aBG );
-
- // #105055# Disable XOR temporarily
- bool bOldXORMode( bXORMode_ );
- bXORMode_ = false;
-
- // copy pixmap #2 (result) to background
- XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
- 0, 0,
- rPosAry.mnDestWidth, rPosAry.mnDestHeight,
- rPosAry.mnDestX, rPosAry.mnDestY );
-
- DBG_TESTTRANS( aBG );
-
- bXORMode_ = bOldXORMode;
-
- XFreeGC( pXDisp, aTmpGC );
- XFlush( pXDisp );
- }
- else
- drawBitmap( rPosAry, rSalBitmap );
-
- if( aFG )
- XFreePixmap( pXDisp, aFG );
-
- if( aBG )
- XFreePixmap( pXDisp, aBG );
+ mpImpl->drawBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
}
bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
{
- // non 8-bit alpha not implemented yet
- if( rAlphaBmp.GetBitCount() != 8 )
- return false;
-
- // horizontal mirroring not implemented yet
- if( rTR.mnDestWidth < 0 )
- return false;
-
- // stretched conversion is not implemented yet
- if( rTR.mnDestWidth != rTR.mnSrcWidth )
- return false;
- if( rTR.mnDestHeight!= rTR.mnSrcHeight )
- return false;
-
- // create destination picture
- Picture aDstPic = GetXRenderPicture();
- if( !aDstPic )
- return false;
-
- const SalDisplay* pSalDisp = GetDisplay();
- const SalVisual& rSalVis = pSalDisp->GetVisual( m_nXScreen );
- Display* pXDisplay = pSalDisp->GetDisplay();
-
- // create source Picture
- int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth();
- const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
- ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( hDrawable_, m_nXScreen, nDepth, rTR );
- if( !pSrcDDB )
- return false;
-
- //#i75249# workaround for ImplGetDDB() giving us back a different depth than
- // we requested. E.g. mask pixmaps are always compatible with the drawable
- // TODO: find an appropriate picture format for these cases
- // then remove the workaround below and the one for #i75531#
- if( nDepth != pSrcDDB->ImplGetDepth() )
- return false;
-
- Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
- if( !aSrcPM )
- return false;
-
- // create source picture
- // TODO: use scoped picture
- Visual* pSrcXVisual = rSalVis.GetVisual();
- XRenderPeer& rPeer = XRenderPeer::GetInstance();
- XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
- if( !pSrcVisFmt )
- return false;
- Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
- if( !aSrcPic )
- return false;
-
- // create alpha Picture
-
- // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
- // problem is that they don't provide an 8bit Pixmap on a non-8bit display
- BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( true );
-
- // an XImage needs its data top_down
- // TODO: avoid wrongly oriented images in upper layers!
- const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
- const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
- char* pAlphaBits = new char[ nImageSize ];
- if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
- memcpy( pAlphaBits, pSrcBits, nImageSize );
- else
- {
- char* pDstBits = pAlphaBits + nImageSize;
- const int nLineSize = pAlphaBuffer->mnScanlineSize;
- for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
- memcpy( pDstBits, pSrcBits, nLineSize );
- }
-
- // the alpha values need to be inverted for XRender
- // TODO: make upper layers use standard alpha
- long* pLDst = (long*)pAlphaBits;
- for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
- *pLDst = ~*pLDst;
-
- char* pCDst = (char*)pLDst;
- for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
- *pCDst = ~*pCDst;
-
- const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
- XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
- pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
- pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
-
- Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, hDrawable_,
- rTR.mnDestWidth, rTR.mnDestHeight, 8 );
-
- XGCValues aAlphaGCV;
- aAlphaGCV.function = GXcopy;
- GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
- XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
- rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
- XFreeGC( pXDisplay, aAlphaGC );
- XFree( pAlphaImg );
- if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
- delete[] pAlphaBits;
-
- const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, true );
-
- XRenderPictureAttributes aAttr;
- aAttr.repeat = int(true);
- Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
- if( !aAlphaPic )
- return false;
-
- // set clipping
- if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
- rPeer.SetPictureClipRegion( aDstPic, mpClipRegion );
-
- // paint source * mask over destination picture
- rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
- rTR.mnSrcX, rTR.mnSrcY, 0, 0,
- rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
-
- rPeer.FreePicture( aAlphaPic );
- XFreePixmap(pXDisplay, aAlphaPM);
- rPeer.FreePicture( aSrcPic );
- return true;
+ return mpImpl->drawAlphaBitmap( rTR, rSrcBitmap, rAlphaBmp );
}
bool X11SalGraphics::drawTransformedBitmap(
@@ -740,191 +192,37 @@ bool X11SalGraphics::drawTransformedBitmap(
const SalBitmap& rSourceBitmap,
const SalBitmap* pAlphaBitmap)
{
- // here direct support for transformed bitmaps can be impemented
- (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
- return false;
+ return mpImpl->drawTransformedBitmap( rNull, rX, rY, rSourceBitmap, pAlphaBitmap );
}
bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
long nHeight, sal_uInt8 nTransparency )
{
- if( ! m_pFrame && ! m_pVDev )
- return false;
-
- if( bPenGC_ || !bBrushGC_ || bXORMode_ )
- return false; // can only perform solid fills without XOR.
-
- if( m_pVDev && m_pVDev->GetDepth() < 8 )
- return false;
-
- Picture aDstPic = GetXRenderPicture();
- if( !aDstPic )
- return false;
-
- const double fTransparency = (100 - nTransparency) * (1.0/100);
- const XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency);
-
- XRenderPeer& rPeer = XRenderPeer::GetInstance();
- rPeer.FillRectangle( PictOpOver,
- aDstPic,
- &aRenderColor,
- nX, nY,
- nWidth, nHeight );
-
- return true;
+ return mpImpl->drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
}
-void X11SalGraphics::drawBitmap( const SalTwoRect&,
- const SalBitmap&,
- SalColor )
+void X11SalGraphics::drawBitmap( const SalTwoRect& rRect,
+ const SalBitmap& rBitmap,
+ SalColor nColor )
{
- OSL_FAIL( "::DrawBitmap with transparent color not supported" );
+ mpImpl->drawBitmap( rRect, rBitmap, nColor );
}
void X11SalGraphics::drawMask( const SalTwoRect& rPosAry,
const SalBitmap &rSalBitmap,
SalColor nMaskColor )
{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- Drawable aDrawable( GetDrawable() );
- Pixmap aStipple( limitXCreatePixmap( pXDisp, aDrawable,
- rPosAry.mnDestWidth,
- rPosAry.mnDestHeight, 1 ) );
-
- if( aStipple )
- {
- SalTwoRect aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
- GC aTmpGC;
- XGCValues aValues;
-
- // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
- aValues.function = GXcopyInverted;
- aValues.foreground = 1, aValues.background = 0;
- aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
- static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aStipple, m_nXScreen, 1, aTwoRect, aTmpGC );
-
- XFreeGC( pXDisp, aTmpGC );
-
- // Set stipple and draw rectangle
- GC aStippleGC( GetStippleGC() );
- int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
-
- XSetStipple( pXDisp, aStippleGC, aStipple );
- XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
- XSetForeground( pXDisp, aStippleGC, GetPixel( nMaskColor ) );
- XFillRectangle( pXDisp, aDrawable, aStippleGC,
- nX, nY,
- rPosAry.mnDestWidth, rPosAry.mnDestHeight );
- XFreePixmap( pXDisp, aStipple );
- XFlush( pXDisp );
- }
- else
- drawBitmap( rPosAry, rSalBitmap );
+ mpImpl->drawMask( rPosAry, rSalBitmap, nMaskColor );
}
SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
{
- if( bPrinter_ && !bVirDev_ )
- return NULL;
-
- bool bFakeWindowBG = false;
-
- // normalize
- if( nDX < 0 )
- {
- nX += nDX;
- nDX = -nDX;
- }
- if ( nDY < 0 )
- {
- nY += nDY;
- nDY = -nDY;
- }
-
- if( bWindow_ && !bVirDev_ )
- {
- XWindowAttributes aAttrib;
-
- XGetWindowAttributes( GetXDisplay(), GetDrawable(), &aAttrib );
- if( aAttrib.map_state != IsViewable )
- bFakeWindowBG = true;
- else
- {
- long nOrgDX = nDX, nOrgDY = nDY;
-
- // clip to window size
- if ( nX < 0 )
- {
- nDX += nX;
- nX = 0;
- }
- if ( nY < 0 )
- {
- nDY += nY;
- nY = 0;
- }
- if( nX + nDX > aAttrib.width )
- nDX = aAttrib.width - nX;
- if( nY + nDY > aAttrib.height )
- nDY = aAttrib.height - nY;
-
- // inside ?
- if( nDX <= 0 || nDY <= 0 )
- {
- bFakeWindowBG = true;
- nDX = nOrgDX;
- nDY = nOrgDY;
- }
- }
- }
-
- X11SalBitmap* pSalBitmap = new X11SalBitmap;
- sal_uInt16 nBitCount = GetBitCount();
-
- if( &GetDisplay()->GetColormap( m_nXScreen ) != &GetColormap() )
- nBitCount = 1;
-
- if( ! bFakeWindowBG )
- pSalBitmap->ImplCreateFromDrawable( GetDrawable(), m_nXScreen, nBitCount, nX, nY, nDX, nDY );
- else
- pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
-
- return pSalBitmap;
+ return mpImpl->getBitmap( nX, nY, nDX, nDY );
}
SalColor X11SalGraphics::getPixel( long nX, long nY )
{
- if( bWindow_ && !bVirDev_ )
- {
- XWindowAttributes aAttrib;
-
- XGetWindowAttributes( GetXDisplay(), GetDrawable(), &aAttrib );
- if( aAttrib.map_state != IsViewable )
- {
- stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
- return 0;
- }
- }
-
- XImage *pXImage = XGetImage( GetXDisplay(),
- GetDrawable(),
- nX, nY,
- 1, 1,
- AllPlanes,
- ZPixmap );
- if( !pXImage )
- {
- stderr0( "X11SalGraphics::GetPixel !XGetImage()\n" );
- return 0;
- }
-
- XColor aXColor;
-
- aXColor.pixel = XGetPixel( pXImage, 0, 0 );
- XDestroyImage( pXImage );
-
- return GetColormap().GetColor( aXColor.pixel );
+ return mpImpl->getPixel( nX, nY );
}
void X11SalGraphics::invert( long nX,
@@ -933,25 +231,7 @@ void X11SalGraphics::invert( long nX,
long nDY,
SalInvert nFlags )
{
- GC pGC;
- if( SAL_INVERT_50 & nFlags )
- {
- pGC = GetInvert50GC();
- XFillRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- else
- {
- if ( SAL_INVERT_TRACKFRAME & nFlags )
- {
- pGC = GetTrackingGC();
- XDrawRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- else
- {
- pGC = GetInvertGC();
- XFillRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- }
+ mpImpl->invert( nX, nY, nDX, nDY, nFlags );
}
bool X11SalGraphics::supportsOperation( OutDevSupportType eType ) const
diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
index 3cd42cdd09a9..3f47712e68ba 100644
--- a/vcl/unx/generic/gdi/salgdi3.cxx
+++ b/vcl/unx/generic/gdi/salgdi3.cxx
@@ -36,7 +36,6 @@
#include <osl/module.hxx>
#include <rtl/tencinfo.h>
#include <sal/alloca.h>
-#include <tools/debug.hxx>
#include <tools/stream.hxx>
#include <vcl/settings.hxx>
#include <vcl/sysdata.hxx>
@@ -59,31 +58,9 @@
#include "unx/salgdi.h"
#include "unx/salunx.h"
#include "unx/salvd.h"
+#include "textrender.hxx"
#include "xrender_peer.hxx"
-#include <config_graphite.h>
-#if ENABLE_GRAPHITE
-#include <graphite_layout.hxx>
-#include <graphite_serverfont.hxx>
-#endif
-
-#include <cairo.h>
-#include <cairo-ft.h>
-#include <cairo-xlib.h>
-#include <cairo-xlib-xrender.h>
-
-struct BOX
-{
- short x1, x2, y1, y2;
-};
-struct _XRegion
-{
- long size;
- long numRects;
- BOX *rects;
- BOX extents;
-};
-
// X11SalGraphics
GC
@@ -113,569 +90,80 @@ X11SalGraphics::GetFontGC()
return pFontGC_;
}
-bool X11SalGraphics::setFont( const FontSelectPattern *pEntry, int nFallbackLevel )
-{
- // release all no longer needed font resources
- for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
- {
- if( mpServerFont[i] != NULL )
- {
- // old server side font is no longer referenced
- GlyphCache::GetInstance().UncacheFont( *mpServerFont[i] );
- mpServerFont[i] = NULL;
- }
- }
-
- // return early if there is no new font
- if( !pEntry )
- return false;
-
- // return early if this is not a valid font for this graphics
- if( !pEntry->mpFontData )
- return false;
-
- // handle the request for a non-native X11-font => use the GlyphCache
- ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
- if( pServerFont != NULL )
- {
- // ignore fonts with e.g. corrupted font files
- if( !pServerFont->TestFont() )
- {
- GlyphCache::GetInstance().UncacheFont( *pServerFont );
- return false;
- }
-
- // register to use the font
- mpServerFont[ nFallbackLevel ] = pServerFont;
-
- // apply font specific-hint settings if needed
- // TODO: also disable it for reference devices
- if( !bPrinter_ )
- {
- ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry );
- pSFE->HandleFontOptions();
- }
-
- return true;
- }
-
- return false;
-}
-
ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize);
-void ImplServerFontEntry::HandleFontOptions( void )
-{
- if( !mpServerFont )
- return;
- if( !mbGotFontOptions )
- {
- // get and cache the font options
- mbGotFontOptions = true;
- mpFontOptions.reset(GetFCFontOptions( *maFontSelData.mpFontData,
- maFontSelData.mnHeight ));
- }
- // apply the font options
- mpServerFont->SetFontOptions( mpFontOptions );
-}
-
-CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
-int CairoFontsCache::mnRefCount = 0;
-
-CairoFontsCache::CairoFontsCache()
-{
- ++mnRefCount;
-}
-
-CairoFontsCache::~CairoFontsCache()
-{
- --mnRefCount;
- if (!mnRefCount && !maLRUFonts.empty())
- {
- LRUFonts::iterator aEnd = maLRUFonts.end();
- for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
- cairo_font_face_destroy((cairo_font_face_t*)aI->first);
- }
-}
-
-void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId)
-{
- maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
- if (maLRUFonts.size() > 8)
- {
- cairo_font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
- maLRUFonts.pop_back();
- }
-}
-
-void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
-{
- LRUFonts::iterator aEnd = maLRUFonts.end();
- for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
- if (aI->second == rId)
- return aI->first;
- return NULL;
-}
-
-namespace
-{
- bool hasRotation(int nRotation)
- {
- return nRotation != 0;
- }
-
- double toRadian(int nDegree10th)
- {
- return (3600 - (nDegree10th)) * M_PI / 1800.0;
- }
-}
-
void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
{
- std::vector<cairo_glyph_t> cairo_glyphs;
- std::vector<int> glyph_extrarotation;
- cairo_glyphs.reserve( 256 );
-
- Point aPos;
- sal_GlyphId aGlyphId;
- for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
- {
- cairo_glyph_t aGlyph;
- aGlyph.index = aGlyphId & GF_IDXMASK;
- aGlyph.x = aPos.X();
- aGlyph.y = aPos.Y();
- cairo_glyphs.push_back(aGlyph);
-
- switch (aGlyphId & GF_ROTMASK)
- {
- case GF_ROTL: // left
- glyph_extrarotation.push_back(1);
- break;
- case GF_ROTR: // right
- glyph_extrarotation.push_back(-1);
- break;
- default:
- glyph_extrarotation.push_back(0);
- break;
- }
- }
-
- if (cairo_glyphs.empty())
- return;
-
- // find a XRenderPictFormat compatible with the Drawable
- XRenderPictFormat* pVisualFormat = GetXRenderFormat();
-
- Display* pDisplay = GetXDisplay();
-
- cairo_surface_t *surface;
-
- if (pVisualFormat)
- {
- surface = cairo_xlib_surface_create_with_xrender_format (
- pDisplay, hDrawable_,
- ScreenOfDisplay(pDisplay, m_nXScreen.getXScreen()),
- pVisualFormat, SAL_MAX_INT16, SAL_MAX_INT16);
- }
- else
- {
- surface = cairo_xlib_surface_create(pDisplay, hDrawable_,
- GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16);
- }
-
- DBG_ASSERT( surface!=NULL, "no cairo surface for text" );
- if( !surface )
- return;
-
- /*
- * It might be ideal to cache surface and cairo context between calls and
- * only destroy it when the drawable changes, but to do that we need to at
- * least change the SalFrame etc impls to dtor the SalGraphics *before* the
- * destruction of the windows they reference
- */
- cairo_t *cr = cairo_create(surface);
- cairo_surface_destroy(surface);
-
- if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
- cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions));
-
- if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
- {
- for (long i = 0; i < mpClipRegion->numRects; ++i)
- {
- cairo_rectangle(cr,
- mpClipRegion->rects[i].x1,
- mpClipRegion->rects[i].y1,
- mpClipRegion->rects[i].x2 - mpClipRegion->rects[i].x1,
- mpClipRegion->rects[i].y2 - mpClipRegion->rects[i].y1);
- }
- cairo_clip(cr);
- }
-
- cairo_set_source_rgb(cr,
- SALCOLOR_RED(nTextColor_)/255.0,
- SALCOLOR_GREEN(nTextColor_)/255.0,
- SALCOLOR_BLUE(nTextColor_)/255.0);
-
- ServerFont& rFont = rLayout.GetServerFont();
-
- FT_Face aFace = rFont.GetFtFace();
- CairoFontsCache::CacheId aId;
- aId.maFace = aFace;
- aId.mpOptions = rFont.GetFontOptions().get();
- aId.mbEmbolden = rFont.NeedsArtificialBold();
-
- cairo_matrix_t m;
- const FontSelectPattern& rFSD = rFont.GetFontSelData();
- int nHeight = rFSD.mnHeight;
- int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
-
- std::vector<int>::const_iterator aEnd = glyph_extrarotation.end();
- std::vector<int>::const_iterator aStart = glyph_extrarotation.begin();
- std::vector<int>::const_iterator aI = aStart;
- while (aI != aEnd)
- {
- int nGlyphRotation = *aI;
-
- std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
-
- size_t nStartIndex = std::distance(aStart, aI);
- size_t nLen = std::distance(aI, aNext);
-
- aId.mbVerticalMetrics = nGlyphRotation != 0.0;
- cairo_font_face_t* font_face = (cairo_font_face_t*)CairoFontsCache::FindCachedFont(aId);
- if (!font_face)
- {
- const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
- void *pPattern = pOptions ? pOptions->GetPattern(aFace, aId.mbEmbolden, aId.mbVerticalMetrics) : NULL;
- if (pPattern)
- font_face = cairo_ft_font_face_create_for_pattern(reinterpret_cast<FcPattern*>(pPattern));
- if (!font_face)
- font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(aFace), rFont.GetLoadFlags());
- CairoFontsCache::CacheFont(font_face, aId);
- }
- cairo_set_font_face(cr, font_face);
-
- cairo_set_font_size(cr, nHeight);
-
- cairo_matrix_init_identity(&m);
-
- if (rLayout.GetOrientation())
- cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
-
- cairo_matrix_scale(&m, nWidth, nHeight);
-
- if (nGlyphRotation)
- {
- cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
-
- cairo_matrix_t em_square;
- cairo_matrix_init_identity(&em_square);
- cairo_get_matrix(cr, &em_square);
-
- cairo_matrix_scale(&em_square, aFace->units_per_EM,
- aFace->units_per_EM);
- cairo_set_matrix(cr, &em_square);
-
- cairo_font_extents_t font_extents;
- cairo_font_extents(cr, &font_extents);
-
- cairo_matrix_init_identity(&em_square);
- cairo_set_matrix(cr, &em_square);
-
- //gives the same positions as pre-cairo conversion, but I don't
- //like them
- double xdiff = 0.0;
- double ydiff = 0.0;
- if (nGlyphRotation == 1)
- {
- ydiff = font_extents.ascent/nHeight;
- xdiff = -font_extents.descent/nHeight;
- }
- else if (nGlyphRotation == -1)
- {
- cairo_text_extents_t text_extents;
- cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
- &text_extents);
-
- xdiff = -text_extents.x_advance/nHeight;
- //to restore an apparent bug in the original X11 impl, replace
- //nHeight with nWidth below
- xdiff += font_extents.descent/nHeight;
- }
- cairo_matrix_translate(&m, xdiff, ydiff);
- }
-
- if (rFont.NeedsArtificialItalic())
- {
- cairo_matrix_t shear;
- cairo_matrix_init_identity(&shear);
- shear.xy = -shear.xx * 0x6000L / 0x10000L;
- cairo_matrix_multiply(&m, &shear, &m);
- }
-
- cairo_set_font_matrix(cr, &m);
- cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
-
-#if OSL_DEBUG_LEVEL > 2
- //draw origin
- cairo_save (cr);
- cairo_rectangle (cr, cairo_glyphs[nStartIndex].x, cairo_glyphs[nStartIndex].y, 5, 5);
- cairo_set_source_rgba (cr, 1, 0, 0, 0.80);
- cairo_fill (cr);
- cairo_restore (cr);
-#endif
-
- aI = aNext;
- }
-
- cairo_destroy(cr);
+ mpTextRenderImpl->DrawServerFontLayout(rLayout);
}
const FontCharMapPtr X11SalGraphics::GetFontCharMap() const
{
- if( !mpServerFont[0] )
- return NULL;
-
- const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
- return pFCMap;
+ return mpTextRenderImpl->GetFontCharMap();
}
bool X11SalGraphics::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const
{
- if (!mpServerFont[0])
- return false;
- return mpServerFont[0]->GetFontCapabilities(rGetImplFontCapabilities);
+ return mpTextRenderImpl->GetFontCapabilities(rGetImplFontCapabilities);
}
// SalGraphics
sal_uInt16 X11SalGraphics::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
{
- sal_uInt16 nRetVal = 0;
- if( !setFont( pEntry, nFallbackLevel ) )
- nRetVal |= SAL_SETFONT_BADFONT;
- if( bPrinter_ || (mpServerFont[ nFallbackLevel ] != NULL) )
- nRetVal |= SAL_SETFONT_USEDRAWTEXTARRAY;
- return nRetVal;
+ return mpTextRenderImpl->SetFont(pEntry, nFallbackLevel);
}
void
X11SalGraphics::SetTextColor( SalColor nSalColor )
{
- if( nTextColor_ != nSalColor )
- {
- nTextColor_ = nSalColor;
- nTextPixel_ = GetPixel( nSalColor );
- bFontGC_ = false;
- }
+ mpTextRenderImpl->SetTextColor(nSalColor);
+ nTextPixel_ = GetPixel( nSalColor );
+ bFontGC_ = false;
}
bool X11SalGraphics::AddTempDevFont( PhysicalFontCollection* pFontCollection,
const OUString& rFileURL,
const OUString& rFontName )
{
- // inform PSP font manager
- OUString aUSystemPath;
- OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFileURL, aUSystemPath ) );
- rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
- OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) );
- psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
- std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName );
- if( aFontIds.empty() )
- return false;
-
- GlyphCache& rGC = X11GlyphCache::GetInstance();
-
- for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI)
- {
- // prepare font data
- psp::FastPrintFontInfo aInfo;
- rMgr.getFontFastInfo( *aI, aInfo );
- aInfo.m_aFamilyName = rFontName;
-
- // inform glyph cache of new font
- ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
- aDFA.mnQuality += 5800;
-
- int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
-
- const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
- rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
- }
-
- // announce new font to device's font list
- rGC.AnnounceFonts( pFontCollection );
- return true;
+ return mpTextRenderImpl->AddTempDevFont(pFontCollection, rFileURL, rFontName);
}
void X11SalGraphics::ClearDevFontCache()
{
- X11GlyphCache& rGC = X11GlyphCache::GetInstance();
- rGC.ClearFontCache();
+ mpTextRenderImpl->ClearDevFontCache();
}
void X11SalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection )
{
- // prepare the GlyphCache using psprint's font infos
- X11GlyphCache& rGC = X11GlyphCache::GetInstance();
-
- psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
- ::std::list< psp::fontID > aList;
- ::std::list< psp::fontID >::iterator it;
- psp::FastPrintFontInfo aInfo;
- rMgr.getFontList( aList );
- for( it = aList.begin(); it != aList.end(); ++it )
- {
- if( !rMgr.getFontFastInfo( *it, aInfo ) )
- continue;
-
- // normalize face number to the GlyphCache
- int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
-
- // inform GlyphCache about this font provided by the PsPrint subsystem
- ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
- aDFA.mnQuality += 4096;
- const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
- rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
- }
-
- // announce glyphcache fonts
- rGC.AnnounceFonts( pFontCollection );
-
- // register platform specific font substitutions if available
- SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
-
- ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
-}
-
-void cairosubcallback(void* pPattern)
-{
- const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
- const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
- if( !pFontOptions )
- return;
- cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
- static_cast<FcPattern*>(pPattern));
-}
-
-ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)
-{
- psp::FastPrintFontInfo aInfo;
-
- aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
- aInfo.m_eItalic = rFontAttributes.GetSlant();
- aInfo.m_eWeight = rFontAttributes.GetWeight();
- aInfo.m_eWidth = rFontAttributes.GetWidthType();
-
- const psp::PrintFontManager& rPFM = psp::PrintFontManager::get();
- return rPFM.getFontOptions(aInfo, nSize, cairosubcallback);
+ mpTextRenderImpl->GetDevFontList(pFontCollection);
}
void
X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel )
{
- if( nFallbackLevel >= MAX_FALLBACK )
- return;
-
- if( mpServerFont[nFallbackLevel] != NULL )
- {
- long rDummyFactor;
- mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
- }
+ mpTextRenderImpl->GetFontMetric(pMetric, nFallbackLevel);
}
bool X11SalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
{
- const int nLevel = aGlyphId >> GF_FONTSHIFT;
- if( nLevel >= MAX_FALLBACK )
- return false;
-
- ServerFont* pSF = mpServerFont[ nLevel ];
- if( !pSF )
- return false;
-
- aGlyphId &= GF_IDXMASK;
- const GlyphMetric& rGM = pSF->GetGlyphMetric(aGlyphId);
- Rectangle aRect( rGM.GetOffset(), rGM.GetSize() );
-
- if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
- {
- double nCos = pSF->mnCos / 65536.0;
- double nSin = pSF->mnSin / 65536.0;
- rRect.Left() = nCos*aRect.Left() + nSin*aRect.Top();
- rRect.Top() = -nSin*aRect.Left() - nCos*aRect.Top();
-
- rRect.Right() = nCos*aRect.Right() + nSin*aRect.Bottom();
- rRect.Bottom() = -nSin*aRect.Right() - nCos*aRect.Bottom();
- }
- else
- rRect = aRect;
-
- return true;
+ return mpTextRenderImpl->GetGlyphBoundRect(aGlyphId, rRect);
}
bool X11SalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId,
::basegfx::B2DPolyPolygon& rPolyPoly )
{
- const int nLevel = aGlyphId >> GF_FONTSHIFT;
- if( nLevel >= MAX_FALLBACK )
- return false;
-
- ServerFont* pSF = mpServerFont[ nLevel ];
- if( !pSF )
- return false;
-
- aGlyphId &= GF_IDXMASK;
- if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) )
- return true;
-
- return false;
+ return mpTextRenderImpl->GetGlyphOutline(aGlyphId, rPolyPoly);
}
SalLayout* X11SalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
{
- SalLayout* pLayout = NULL;
-
- if( mpServerFont[ nFallbackLevel ]
- && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
- {
-#if ENABLE_GRAPHITE
- // Is this a Graphite font?
- if (!bDisableGraphite_ &&
- GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
- {
- pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
- }
- else
-#endif
- pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
- }
-
- return pLayout;
+ return mpTextRenderImpl->GetTextLayout(rArgs, nFallbackLevel);
}
-SystemFontData X11SalGraphics::GetSysFontData( int nFallbacklevel ) const
+SystemFontData X11SalGraphics::GetSysFontData( int nFallbackLevel ) const
{
- SystemFontData aSysFontData;
- aSysFontData.nSize = sizeof( SystemFontData );
- aSysFontData.nFontId = 0;
-
- if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
- if (nFallbacklevel < 0 ) nFallbacklevel = 0;
-
- if (mpServerFont[nFallbacklevel] != NULL)
- {
- ServerFont* rFont = mpServerFont[nFallbacklevel];
- aSysFontData.nFontId = rFont->GetFtFace();
- aSysFontData.nFontFlags = rFont->GetLoadFlags();
- aSysFontData.bFakeBold = rFont->NeedsArtificialBold();
- aSysFontData.bFakeItalic = rFont->NeedsArtificialItalic();
- aSysFontData.bAntialias = rFont->GetAntialiasAdvice();
- aSysFontData.bVerticalCharacterType = rFont->GetFontSelData().mbVertical;
- }
-
- return aSysFontData;
+ return mpTextRenderImpl->GetSysFontData(nFallbackLevel);
}
bool X11SalGraphics::CreateFontSubset(
@@ -688,49 +176,23 @@ bool X11SalGraphics::CreateFontSubset(
FontSubsetInfo& rInfo
)
{
- // in this context the pFont->GetFontId() is a valid PSP
- // font since they are the only ones left after the PDF
- // export has filtered its list of subsettable fonts (for
- // which this method was created). The correct way would
- // be to have the GlyphCache search for the PhysicalFontFace pFont
- psp::fontID aFont = pFont->GetFontId();
-
- psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
- bool bSuccess = rMgr.createFontSubset( rInfo,
- aFont,
- rToFile,
- pGlyphIds,
- pEncoding,
- pWidths,
- nGlyphCount );
- return bSuccess;
+ return mpTextRenderImpl->CreateFontSubset(rToFile, pFont,
+ pGlyphIds, pEncoding, pWidths, nGlyphCount, rInfo);
}
const void* X11SalGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
{
- // in this context the pFont->GetFontId() is a valid PSP
- // font since they are the only ones left after the PDF
- // export has filtered its list of subsettable fonts (for
- // which this method was created). The correct way would
- // be to have the GlyphCache search for the PhysicalFontFace pFont
- psp::fontID aFont = pFont->GetFontId();
- return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
+ return mpTextRenderImpl->GetEmbedFontData(pFont, pUnicodes, pWidths, rInfo, pDataLen);
}
void X11SalGraphics::FreeEmbedFontData( const void* pData, long nLen )
{
- GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
+ mpTextRenderImpl->FreeEmbedFontData(pData, nLen);
}
const Ucs2SIntMap* X11SalGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
{
- // in this context the pFont->GetFontId() is a valid PSP
- // font since they are the only ones left after the PDF
- // export has filtered its list of subsettable fonts (for
- // which this method was created). The correct way would
- // be to have the GlyphCache search for the PhysicalFontFace pFont
- psp::fontID aFont = pFont->GetFontId();
- return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
+ return mpTextRenderImpl->GetFontEncodingVector(pFont, pNonEncoded);
}
void X11SalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
@@ -738,13 +200,7 @@ void X11SalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
Int32Vector& rWidths,
Ucs2UIntMap& rUnicodeEnc )
{
- // in this context the pFont->GetFontId() is a valid PSP
- // font since they are the only ones left after the PDF
- // export has filtered its list of subsettable fonts (for
- // which this method was created). The correct way would
- // be to have the GlyphCache search for the PhysicalFontFace pFont
- psp::fontID aFont = pFont->GetFontId();
- GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+ mpTextRenderImpl->GetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx
index 83925d9f3186..8e08cc2019fa 100644
--- a/vcl/unx/generic/gdi/salvd.cxx
+++ b/vcl/unx/generic/gdi/salvd.cxx
@@ -102,14 +102,14 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
if (m_pDeleteColormap != pOrigDeleteColormap)
delete pOrigDeleteColormap;
- const Drawable aVdevDrawable = pDevice->GetDrawable();
- SetDrawable( aVdevDrawable, m_nXScreen );
-
m_pVDev = pDevice;
m_pFrame = NULL;
bWindow_ = pDisplay->IsDisplay();
bVirDev_ = true;
+
+ const Drawable aVdevDrawable = pDevice->GetDrawable();
+ SetDrawable( aVdevDrawable, m_nXScreen );
}
bool X11SalVirtualDevice::Init( SalDisplay *pDisplay,
diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx
new file mode 100644
index 000000000000..2533107908c2
--- /dev/null
+++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx
@@ -0,0 +1,129 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "x11cairotextrender.hxx"
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+#include "unx/salvd.h"
+
+#include "gcach_xpeer.hxx"
+
+#include <cairo.h>
+#include <cairo-ft.h>
+
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+
+struct BOX
+{
+ short x1, x2, y1, y2;
+};
+struct _XRegion
+{
+ long size;
+ long numRects;
+ BOX *rects;
+ BOX extents;
+};
+
+X11CairoTextRender::X11CairoTextRender(bool bPrinter, X11SalGraphics& rParent):
+ CairoTextRender(bPrinter),
+ mrParent(rParent)
+{
+}
+
+GlyphCache& X11CairoTextRender::getPlatformGlyphCache()
+{
+ return X11GlyphCache::GetInstance();
+}
+
+cairo_surface_t* X11CairoTextRender::getCairoSurface()
+{
+ // find a XRenderPictFormat compatible with the Drawable
+ XRenderPictFormat* pVisualFormat = mrParent.GetXRenderFormat();
+
+ Display* pDisplay = mrParent.GetXDisplay();
+
+ cairo_surface_t* surface = NULL;
+ if (pVisualFormat)
+ {
+ surface = cairo_xlib_surface_create_with_xrender_format (
+ pDisplay, mrParent.hDrawable_,
+ ScreenOfDisplay(pDisplay, mrParent.m_nXScreen.getXScreen()),
+ pVisualFormat, SAL_MAX_INT16, SAL_MAX_INT16);
+ }
+ else
+ {
+ surface = cairo_xlib_surface_create(pDisplay, mrParent.hDrawable_,
+ mrParent.GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16);
+ }
+
+ return surface;
+}
+
+void X11CairoTextRender::clipRegion(cairo_t* cr)
+{
+ Region pClipRegion = mrParent.mpClipRegion;
+ if( pClipRegion && !XEmptyRegion( pClipRegion ) )
+ {
+ for (long i = 0; i < pClipRegion->numRects; ++i)
+ {
+ cairo_rectangle(cr,
+ pClipRegion->rects[i].x1,
+ pClipRegion->rects[i].y1,
+ pClipRegion->rects[i].x2 - pClipRegion->rects[i].x1,
+ pClipRegion->rects[i].y2 - pClipRegion->rects[i].y1);
+ }
+ cairo_clip(cr);
+ }
+}
+
+size_t X11CairoTextRender::GetWidth() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nWidth;
+ else if( mrParent.m_pVDev )
+ {
+ long nWidth = 0;
+ long nHeight = 0;
+ mrParent.m_pVDev->GetSize( nWidth, nHeight );
+ return nWidth;
+ }
+ return 1;
+}
+
+size_t X11CairoTextRender::GetHeight() const
+{
+ if( mrParent.m_pFrame )
+ return mrParent.m_pFrame->maGeometry.nHeight;
+ else if( mrParent.m_pVDev )
+ {
+ long nWidth = 0;
+ long nHeight = 0;
+ mrParent.m_pVDev->GetSize( nWidth, nHeight );
+ return nHeight;
+ }
+ return 1;
+}
+
+void X11CairoTextRender::drawSurface(cairo_t* /*cr*/)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/x11cairotextrender.hxx b/vcl/unx/generic/gdi/x11cairotextrender.hxx
new file mode 100644
index 000000000000..fb0c130ab292
--- /dev/null
+++ b/vcl/unx/generic/gdi/x11cairotextrender.hxx
@@ -0,0 +1,50 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_UNX_GENERIC_GDI_X11CAIROTEXTRENDER_HXX
+#define INCLUDED_VCL_UNX_GENERIC_GDI_X11CAIROTEXTRENDER_HXX value
+
+#include "cairotextrender.hxx"
+
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+
+#include "unx/salgdi.h"
+
+class X11CairoTextRender : public CairoTextRender
+{
+protected:
+ X11SalGraphics& mrParent;
+
+protected:
+ size_t GetWidth() const;
+ size_t GetHeight() const;
+
+public:
+ X11CairoTextRender(bool bPrinter, X11SalGraphics& rParent);
+
+ virtual GlyphCache& getPlatformGlyphCache() SAL_OVERRIDE;
+ virtual cairo_surface_t* getCairoSurface() SAL_OVERRIDE;
+ virtual void clipRegion(cairo_t* cr) SAL_OVERRIDE;
+ virtual void drawSurface(cairo_t* cr) SAL_OVERRIDE;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/x11windowprovider.cxx b/vcl/unx/generic/gdi/x11windowprovider.cxx
new file mode 100644
index 000000000000..5eaa3f612c45
--- /dev/null
+++ b/vcl/unx/generic/gdi/x11windowprovider.cxx
@@ -0,0 +1,16 @@
+/* -*- 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/.
+ */
+
+#include "unx/x11windowprovider.hxx"
+
+X11WindowProvider::~X11WindowProvider()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 0bda729feb22..6c98968f9a93 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -4268,4 +4268,9 @@ void X11SalFrame::EndSetClipRegion()
}
+Window X11SalFrame::GetX11Window()
+{
+ return mhWindow;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index bab4f5c6f888..50cb193fb95a 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -26,6 +26,7 @@
#include "unx/gtk/gtkinst.hxx"
#include "unx/gtk/gtkgdi.hxx"
+#include "unx/pixmap.hxx"
#include "unx/saldata.hxx"
#include "unx/saldisp.hxx"
@@ -257,6 +258,71 @@ static int getFrameWidth(GtkWidget* widget);
static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect );
+
+/************************************************************************
+ * GDK implementation of X11Pixmap
+ ************************************************************************/
+
+class GdkX11Pixmap : public X11Pixmap
+{
+public:
+ GdkX11Pixmap( int nWidth, int nHeight, int nDepth );
+ GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow );
+ virtual ~GdkX11Pixmap();
+
+ GdkPixmap* GetGdkPixmap() const;
+ GdkDrawable* GetGdkDrawable() const;
+
+protected:
+ GdkPixmap* mpGdkPixmap;
+};
+
+GdkX11Pixmap::GdkX11Pixmap( int nWidth, int nHeight, int nDepth )
+{
+ mpGdkPixmap = gdk_pixmap_new( NULL, nWidth, nHeight, nDepth );
+
+ //mpDisplay = ?
+ mnScreen = SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(mpGdkPixmap) ) ) );
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ mnDepth = nDepth;
+ mpPixmap = GDK_PIXMAP_XID( mpGdkPixmap );
+}
+
+GdkX11Pixmap::GdkX11Pixmap( X11Pixmap& rOther, GdkWindow *pWindow )
+: X11Pixmap( rOther )
+{
+ GdkColormap* pColormap;
+
+#if GTK_CHECK_VERSION(2,10,0)
+ GdkScreen *pScreen = gdk_window_get_screen( pWindow );
+ mpGdkPixmap = gdk_pixmap_foreign_new_for_screen( pScreen, mpPixmap,
+ mnWidth, mnHeight,
+ mnDepth );
+#else
+ mpGdkPixmap = gdk_pixmap_foreign_new( mpPixmap );
+#endif
+
+ pColormap = gdk_drawable_get_colormap( pWindow );
+ gdk_drawable_set_colormap( GDK_DRAWABLE (mpGdkPixmap), pColormap );
+}
+
+GdkX11Pixmap::~GdkX11Pixmap()
+{
+ g_object_unref( mpGdkPixmap );
+}
+
+GdkPixmap* GdkX11Pixmap::GetGdkPixmap() const
+{
+ return mpGdkPixmap;
+}
+
+GdkDrawable* GdkX11Pixmap::GetGdkDrawable() const
+{
+ return GDK_DRAWABLE( mpGdkPixmap );
+}
+
+
/*********************************************************
* PixmapCache
*********************************************************/
@@ -271,13 +337,13 @@ class NWPixmapCacheData
public:
ControlType m_nType;
ControlState m_nState;
- Rectangle m_pixmapRect;
- GdkPixmap* m_pixmap;
+ Rectangle m_pixmapRect;
+ GdkX11Pixmap* m_pixmap;
NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {}
~NWPixmapCacheData()
{ SetPixmap( NULL ); };
- void SetPixmap( GdkPixmap* pPixmap );
+ void SetPixmap( GdkX11Pixmap* pPixmap );
};
class NWPixmapCache
@@ -294,8 +360,8 @@ public:
{ delete [] pData; m_idx = 0; m_size = n; pData = new NWPixmapCacheData[m_size]; }
int GetSize() const { return m_size; }
- bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap );
- void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap );
+ bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap );
+ void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap );
void ThemeChanged();
};
@@ -312,15 +378,12 @@ public:
// --- implementation ---
-void NWPixmapCacheData::SetPixmap( GdkPixmap* pPixmap )
+void NWPixmapCacheData::SetPixmap( GdkX11Pixmap* pPixmap )
{
if( m_pixmap )
- g_object_unref( m_pixmap );
+ delete m_pixmap;
m_pixmap = pPixmap;
-
- if( m_pixmap )
- g_object_ref( m_pixmap );
}
NWPixmapCache::NWPixmapCache( SalX11Screen nScreen )
@@ -346,7 +409,7 @@ void NWPixmapCache::ThemeChanged()
pData[i].SetPixmap( NULL );
}
-bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap )
+bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap** pPixmap )
{
aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
int i;
@@ -365,7 +428,7 @@ bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectang
return false;
}
-void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap )
+void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkX11Pixmap* pPixmap )
{
if( !(aState & CTRL_CACHING_ALLOWED) )
return;
@@ -801,7 +864,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType,
clipList aClip;
GdkDrawable* gdkDrawable = GDK_DRAWABLE( GetGdkWindow() );
- GdkPixmap* pixmap = NULL;
+ GdkX11Pixmap* pixmap = NULL;
Rectangle aPixmapRect;
if( ( bNeedPixmapPaint )
&& nType != CTRL_SCROLLBAR
@@ -819,7 +882,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType,
pixmap = NWGetPixmapFromScreen( aPixmapRect );
if( ! pixmap )
return false;
- gdkDrawable = GDK_DRAWABLE( pixmap );
+ gdkDrawable = pixmap->GetGdkDrawable();
aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() );
aClip.push_back( aCtrlRect );
}
@@ -956,7 +1019,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType,
if( pixmap )
{
returnVal = NWRenderPixmapToScreen( pixmap, aPixmapRect ) && returnVal;
- g_object_unref( pixmap );
+ delete pixmap;
}
return( returnVal );
@@ -1742,7 +1805,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
{
assert(aValue.getType() == CTRL_SCROLLBAR);
const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(aValue);
- GdkPixmap* pixmap = NULL;
+ GdkX11Pixmap* pixmap = NULL;
Rectangle pixmapRect, scrollbarRect;
GtkStateType stateType;
GtkShadowType shadowType;
@@ -1930,7 +1993,7 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
w = pixmapRect.GetWidth();
h = pixmapRect.GetHeight();
- GdkDrawable* const &gdkDrawable = GDK_DRAWABLE( pixmap );
+ GdkDrawable* const &gdkDrawable = pixmap->GetGdkDrawable();
GdkRectangle* gdkRect = NULL;
NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
@@ -2051,14 +2114,10 @@ bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
arrowRect.GetWidth(), arrowRect.GetHeight() );
}
- if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
- {
- g_object_unref( pixmap );
- return false;
- }
- g_object_unref( pixmap );
+ bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect );
+ delete pixmap;
- return true;
+ return bRet;
}
static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect )
@@ -2282,7 +2341,8 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
const ImplControlValue& aValue,
const OUString& rCaption )
{
- GdkPixmap * pixmap;
+ GdkX11Pixmap * pixmap;
+ GdkPixmap * gdkPixmap;
Rectangle pixmapRect;
GtkStateType stateType;
GtkShadowType shadowType;
@@ -2326,9 +2386,10 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
pixmap = NWGetPixmapFromScreen( pixmapRect );
if ( !pixmap )
return false;
+ gdkPixmap = pixmap->GetGdkPixmap();
// First render background
- gtk_paint_flat_box(m_pWindow->style,pixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
+ gtk_paint_flat_box(m_pWindow->style,gdkPixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
-pixmapRect.Left(),
-pixmapRect.Top(),
pixmapRect.Right(),
@@ -2348,7 +2409,7 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
aEditBoxRect.setX( 0 );
aEditBoxRect.setY( 0 );
- NWPaintOneEditBox( m_nXScreen, pixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
+ NWPaintOneEditBox( m_nXScreen, gdkPixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
}
NWSetWidgetState( gWidgetData[m_nXScreen].gSpinButtonWidget, nState, stateType );
@@ -2359,23 +2420,19 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
Rectangle shadowRect( upBtnRect );
shadowRect.Union( downBtnRect );
- gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, pixmap, GTK_STATE_NORMAL, shadowType, NULL,
+ gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, gdkPixmap, GTK_STATE_NORMAL, shadowType, NULL,
gWidgetData[m_nXScreen].gSpinButtonWidget, "spinbutton",
(shadowRect.Left() - pixmapRect.Left()), (shadowRect.Top() - pixmapRect.Top()),
shadowRect.GetWidth(), shadowRect.GetHeight() );
}
- NWPaintOneSpinButton( m_nXScreen, pixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
- NWPaintOneSpinButton( m_nXScreen, pixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
+ NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
+ NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
- if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
- {
- g_object_unref( pixmap );
- return false;
- }
+ bool bRet = NWRenderPixmapToScreen( pixmap, pixmapRect );
+ delete pixmap;
- g_object_unref( pixmap );
- return true;
+ return bRet;
}
static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen,
@@ -2609,7 +2666,8 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
const OUString& )
{
OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM );
- GdkPixmap * pixmap;
+ GdkX11Pixmap * pixmap;
+ GdkPixmap * gdkPixmap;
Rectangle pixmapRect;
Rectangle tabRect;
GtkStateType stateType;
@@ -2681,14 +2739,15 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
return NWRenderPixmapToScreen( pixmap, pixmapRect );
}
- pixmap = gdk_pixmap_new( NULL, pixmapRect.GetWidth(), pixmapRect.GetHeight(),
- GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
+ pixmap = new GdkX11Pixmap( pixmapRect.GetWidth(), pixmapRect.GetHeight(),
+ GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
+ gdkPixmap = pixmap->GetGdkPixmap();
GdkRectangle paintRect;
paintRect.x = paintRect.y = 0;
paintRect.width = pixmapRect.GetWidth();
paintRect.height = pixmapRect.GetHeight();
- gtk_paint_flat_box( m_pWindow->style, pixmap, GTK_STATE_NORMAL,
+ gtk_paint_flat_box( m_pWindow->style, gdkPixmap, GTK_STATE_NORMAL,
GTK_SHADOW_NONE, &paintRect, m_pWindow, "base",
-rControlRectangle.Left(),
-rControlRectangle.Top(),
@@ -2703,7 +2762,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
break;
case CTRL_TAB_PANE:
- gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
+ gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
(char *)"notebook", 0, 0, pixmapRect.GetWidth(), pixmapRect.GetHeight(), GTK_POS_TOP, 0, 0 );
break;
@@ -2712,7 +2771,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
stateType = ( nState & CTRL_STATE_SELECTED ) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE;
// First draw the background
- gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap,
+ gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap,
GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
-rControlRectangle.Left(),
-rControlRectangle.Top(),
@@ -2721,17 +2780,17 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
// Now the tab itself
if( nState & CTRL_STATE_ROLLOVER )
- g_object_set_data(G_OBJECT(pixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE));
+ g_object_set_data(G_OBJECT(gdkPixmap),tabPrelitDataName,reinterpret_cast<gpointer>(TRUE));
- gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
+ gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, gdkPixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
(char *)"tab", (tabRect.Left() - pixmapRect.Left()), (tabRect.Top() - pixmapRect.Top()),
tabRect.GetWidth(), tabRect.GetHeight(), GTK_POS_BOTTOM );
- g_object_steal_data(G_OBJECT(pixmap),tabPrelitDataName);
+ g_object_steal_data(G_OBJECT(gdkPixmap),tabPrelitDataName);
if ( nState & CTRL_STATE_SELECTED )
{
- gtk_paint_flat_box( m_pWindow->style, pixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
+ gtk_paint_flat_box( m_pWindow->style, gdkPixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
"base", 0, (pixmapRect.GetHeight() - 1), pixmapRect.GetWidth(), 1 );
}
break;
@@ -2747,8 +2806,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
else
aCachePage.Fill( nType, nState, pixmapRect, pixmap );
- bool bSuccess = NWRenderPixmapToScreen(pixmap, pixmapRect);
- g_object_unref( pixmap );
+ bool bSuccess = NWRenderPixmapToScreen( pixmap, pixmapRect );
return bSuccess;
}
@@ -3324,11 +3382,11 @@ bool GtkSalGraphics::NWPaintGTKListNode(
break;
}
- GdkPixmap* pixmap = NWGetPixmapFromScreen( aRect );
+ GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( aRect );
if( ! pixmap )
return false;
- GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+ GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style,
pixDrawable,
stateType,
@@ -3339,7 +3397,7 @@ bool GtkSalGraphics::NWPaintGTKListNode(
eStyle );
bool bRet = NWRenderPixmapToScreen( pixmap, aRect );
- g_object_unref( pixmap );
+ delete pixmap;
return bRet;
}
@@ -3360,11 +3418,11 @@ bool GtkSalGraphics::NWPaintGTKProgress(
long nProgressWidth = rValue.getNumericVal();
- GdkPixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
+ GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
if( ! pixmap )
return false;
- GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+ GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
// paint background
gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable,
@@ -3408,7 +3466,7 @@ bool GtkSalGraphics::NWPaintGTKProgress(
}
bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
- g_object_unref( pixmap );
+ delete pixmap;
return bRet;
}
@@ -3430,11 +3488,11 @@ bool GtkSalGraphics::NWPaintGTKSlider(
const SliderValue* pVal = static_cast<const SliderValue*>(&rValue);
- GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
+ GdkX11Pixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
if( ! pixmap )
return false;
- GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
+ GdkDrawable* const &pixDrawable = pixmap->GetGdkDrawable();
GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA)
? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale)
: GTK_WIDGET(gWidgetData[m_nXScreen].gVScale);
@@ -3496,7 +3554,7 @@ bool GtkSalGraphics::NWPaintGTKSlider(
}
bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
- g_object_unref( pixmap );
+ delete pixmap;
return bRet;
}
@@ -4070,62 +4128,28 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
* Create a GdkPixmap filled with the contents of an area of an Xlib window
************************************************************************/
-GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
+GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
{
- // Create a new pixmap to hold the composite of the window background and the control
- GdkPixmap * pPixmap = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 );
- GdkGC * pPixmapGC = gdk_gc_new( pPixmap );
-
- if( !pPixmap || !pPixmapGC )
- {
- if ( pPixmap )
- g_object_unref( pPixmap );
- if ( pPixmapGC )
- g_object_unref( pPixmapGC );
- std::fprintf( stderr, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" );
- return( NULL );
- }
-
- // Copy the background of the screen into a composite pixmap
- CopyScreenArea( GetXDisplay(),
- GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
- gdk_x11_drawable_get_xid(pPixmap),
- SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
- gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap ) ),
- gdk_x11_gc_get_xgc(pPixmapGC),
- srcRect.Left(), srcRect.Top(), srcRect.GetWidth(), srcRect.GetHeight(), 0, 0 );
-
- g_object_unref( pPixmapGC );
- return( pPixmap );
+ X11Pixmap* pPixmap;
+ GdkX11Pixmap* pResult;
+
+ pPixmap = GetPixmapFromScreen( srcRect );
+ if( pPixmap == NULL )
+ return NULL;
+
+ pResult = new GdkX11Pixmap( *pPixmap, GetGdkWindow() );
+ delete pPixmap;
+
+ return pResult;
}
/************************************************************************
* Copy an alpha pixmap to screen using a gc with clipping
************************************************************************/
-bool GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect )
+bool GtkSalGraphics::NWRenderPixmapToScreen( GdkX11Pixmap* pPixmap, Rectangle dstRect )
{
- // The GC can't be null, otherwise we'd have no clip region
- GC aFontGC = GetFontGC();
- if( aFontGC == NULL )
- {
- std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" );
- return false;
- }
-
- if ( !pPixmap )
- return false;
-
- // Copy the background of the screen into a composite pixmap
- CopyScreenArea( GetXDisplay(),
- GDK_DRAWABLE_XID(pPixmap),
- SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
- gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ),
- GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
- aFontGC,
- 0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() );
-
- return true;
+ return RenderPixmapToScreen( pPixmap, dstRect.Left(), dstRect.Top() );
}
/************************************************************************
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index b39875f99d2a..03cf9df414ce 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -4508,4 +4508,9 @@ Size GtkSalDisplay::GetScreenSize( int nDisplayScreen )
return Size( aRect.GetWidth(), aRect.GetHeight() );
}
+Window GtkSalFrame::GetX11Window()
+{
+ return widget_get_xid(m_pWindow);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx
new file mode 100644
index 000000000000..453033fa5efb
--- /dev/null
+++ b/vcl/win/source/gdi/gdiimpl.cxx
@@ -0,0 +1,2371 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "gdiimpl.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <svsys.h>
+#include <rtl/strbuf.hxx>
+#include <tools/debug.hxx>
+#include <tools/poly.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <win/wincomp.hxx>
+#include <win/saldata.hxx>
+#include <win/salgdi.h>
+#include "win/salbmp.h"
+#include <vcl/salbtype.hxx>
+#include <win/salframe.h>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+#include "outdata.hxx"
+#include "win/salids.hrc"
+
+#if defined _MSC_VER
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#endif
+
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+
+#ifdef __MINGW32__
+#ifdef GetObject
+#undef GetObject
+#endif
+#endif
+
+#include <gdiplus.h>
+#include <gdiplusenums.h>
+#include <gdipluscolor.h>
+
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+#define SAL_POLYPOLYCOUNT_STACKBUF 8
+#define SAL_POLYPOLYPOINTS_STACKBUF 64
+
+#define DITHER_PAL_DELTA 51
+#define DITHER_PAL_STEPS 6
+#define DITHER_PAL_COUNT (DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS)
+#define DITHER_MAX_SYSCOLOR 16
+#define DITHER_EXTRA_COLORS 1
+#define DMAP( _def_nVal, _def_nThres ) ((pDitherDiff[_def_nVal]>(_def_nThres))?pDitherHigh[_def_nVal]:pDitherLow[_def_nVal])
+
+#define SAL_POLY_STACKBUF 32
+#define USE_GDI_BEZIERS
+
+namespace {
+
+// #100127# draw an array of points which might also contain bezier control points
+void ImplRenderPath( HDC hdc, sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
+{
+ if( nPoints )
+ {
+ sal_uInt16 i;
+ // TODO: profile whether the following options are faster:
+ // a) look ahead and draw consecutive bezier or line segments by PolyBezierTo/PolyLineTo resp.
+ // b) convert our flag array to window's and use PolyDraw
+
+ MoveToEx( hdc, pPtAry->mnX, pPtAry->mnY, NULL );
+ ++pPtAry; ++pFlgAry;
+
+ for( i=1; i<nPoints; ++i, ++pPtAry, ++pFlgAry )
+ {
+ if( *pFlgAry != POLY_CONTROL )
+ {
+ LineTo( hdc, pPtAry->mnX, pPtAry->mnY );
+ }
+ else if( nPoints - i > 2 )
+ {
+ PolyBezierTo( hdc, reinterpret_cast<const POINT*>(pPtAry), 3 );
+ i += 2; pPtAry += 2; pFlgAry += 2;
+ }
+ }
+ }
+}
+
+// #100127# Fill point and flag memory from array of points which
+// might also contain bezier control points for the PolyDraw() GDI method
+// Make sure pWinPointAry and pWinFlagAry are big enough
+void ImplPreparePolyDraw( bool bCloseFigures,
+ sal_uLong nPoly,
+ const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry,
+ const BYTE* const* pFlgAry,
+ POINT* pWinPointAry,
+ BYTE* pWinFlagAry )
+{
+ sal_uLong nCurrPoly;
+ for( nCurrPoly=0; nCurrPoly<nPoly; ++nCurrPoly )
+ {
+ const POINT* pCurrPoint = reinterpret_cast<const POINT*>( *pPtAry++ );
+ const BYTE* pCurrFlag = *pFlgAry++;
+ const sal_uInt32 nCurrPoints = *pPoints++;
+ const bool bHaveFlagArray( pCurrFlag );
+ sal_uLong nCurrPoint;
+
+ if( nCurrPoints )
+ {
+ // start figure
+ *pWinPointAry++ = *pCurrPoint++;
+ *pWinFlagAry++ = PT_MOVETO;
+ ++pCurrFlag;
+
+ for( nCurrPoint=1; nCurrPoint<nCurrPoints; )
+ {
+ // #102067# Check existence of flag array
+ if( bHaveFlagArray &&
+ ( nCurrPoint + 2 ) < nCurrPoints )
+ {
+ BYTE P4( pCurrFlag[ 2 ] );
+
+ if( ( POLY_CONTROL == pCurrFlag[ 0 ] ) &&
+ ( POLY_CONTROL == pCurrFlag[ 1 ] ) &&
+ ( POLY_NORMAL == P4 || POLY_SMOOTH == P4 || POLY_SYMMTR == P4 ) )
+ {
+ // control point one
+ *pWinPointAry++ = *pCurrPoint++;
+ *pWinFlagAry++ = PT_BEZIERTO;
+
+ // control point two
+ *pWinPointAry++ = *pCurrPoint++;
+ *pWinFlagAry++ = PT_BEZIERTO;
+
+ // end point
+ *pWinPointAry++ = *pCurrPoint++;
+ *pWinFlagAry++ = PT_BEZIERTO;
+
+ nCurrPoint += 3;
+ pCurrFlag += 3;
+ continue;
+ }
+ }
+
+ // regular line point
+ *pWinPointAry++ = *pCurrPoint++;
+ *pWinFlagAry++ = PT_LINETO;
+ ++pCurrFlag;
+ ++nCurrPoint;
+ }
+
+ // end figure?
+ if( bCloseFigures )
+ pWinFlagAry[-1] |= PT_CLOSEFIGURE;
+ }
+ }
+}
+
+
+static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] =
+{
+{ 0, 0, 0, 0 },
+{ 0, 0, 0x80, 0 },
+{ 0, 0x80, 0, 0 },
+{ 0, 0x80, 0x80, 0 },
+{ 0x80, 0, 0, 0 },
+{ 0x80, 0, 0x80, 0 },
+{ 0x80, 0x80, 0, 0 },
+{ 0x80, 0x80, 0x80, 0 },
+{ 0xC0, 0xC0, 0xC0, 0 },
+{ 0, 0, 0xFF, 0 },
+{ 0, 0xFF, 0, 0 },
+{ 0, 0xFF, 0xFF, 0 },
+{ 0xFF, 0, 0, 0 },
+{ 0xFF, 0, 0xFF, 0 },
+{ 0xFF, 0xFF, 0, 0 },
+{ 0xFF, 0xFF, 0xFF, 0 }
+};
+
+static PALETTEENTRY aImplExtraColor1 =
+{
+ 0, 184, 255, 0
+};
+
+static BYTE aOrdDither8Bit[8][8] =
+{
+ { 0, 38, 9, 48, 2, 40, 12, 50 },
+ { 25, 12, 35, 22, 28, 15, 37, 24 },
+ { 6, 44, 3, 41, 8, 47, 5, 44 },
+ { 32, 19, 28, 16, 34, 21, 31, 18 },
+ { 1, 40, 11, 49, 0, 39, 10, 48 },
+ { 27, 14, 36, 24, 26, 13, 36, 23 },
+ { 8, 46, 4, 43, 7, 45, 4, 42 },
+ { 33, 20, 30, 17, 32, 20, 29, 16 }
+};
+
+static BYTE aOrdDither16Bit[8][8] =
+{
+ { 0, 6, 1, 7, 0, 6, 1, 7 },
+ { 4, 2, 5, 3, 4, 2, 5, 3 },
+ { 1, 7, 0, 6, 1, 7, 0, 6 },
+ { 5, 3, 4, 2, 5, 3, 4, 2 },
+ { 0, 6, 1, 7, 0, 6, 1, 7 },
+ { 4, 2, 5, 3, 4, 2, 5, 3 },
+ { 1, 7, 0, 6, 1, 7, 0, 6 },
+ { 5, 3, 4, 2, 5, 3, 4, 2 }
+};
+
+SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+ if ( nROPColor == SAL_ROP_0 )
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ return nSalColor;
+}
+
+int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
+{
+ // dither color?
+ if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) )
+ return TRUE;
+
+ PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry;
+
+ // standard palette color?
+ for ( sal_uInt16 i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ )
+ {
+ if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue )
+ return TRUE;
+ }
+
+ // extra color?
+ if ( aImplExtraColor1.peRed == nRed &&
+ aImplExtraColor1.peGreen == nGreen &&
+ aImplExtraColor1.peBlue == nBlue )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+}
+
+WinSalGraphicsImpl::WinSalGraphicsImpl(WinSalGraphics& rParent):
+ mrParent(rParent),
+ mbXORMode(false),
+ mhPen(0),
+ mhBrush(0)
+{
+}
+
+WinSalGraphicsImpl::~WinSalGraphicsImpl()
+{
+ if ( mhPen )
+ {
+ if ( !mbStockPen )
+ DeletePen( mhPen );
+ }
+
+ if ( mhBrush )
+ {
+ if ( !mbStockBrush )
+ DeleteBrush( mhBrush );
+ }
+
+}
+
+void WinSalGraphicsImpl::freeResources()
+{
+}
+
+bool WinSalGraphicsImpl::drawEPS(long, long, long, long, void*, sal_uLong)
+{
+ return false;
+}
+
+void WinSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
+{
+ HDC hSrcDC;
+ DWORD nRop;
+
+ if ( pSrcGraphics )
+ hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC();
+ else
+ hSrcDC = mrParent.getHDC();
+
+ if ( mbXORMode )
+ nRop = SRCINVERT;
+ else
+ nRop = SRCCOPY;
+
+ if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
+ (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
+ {
+ BitBlt( mrParent.getHDC(),
+ (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
+ (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
+ hSrcDC,
+ (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
+ nRop );
+ }
+ else
+ {
+ int nOldStretchMode = SetStretchBltMode( mrParent.getHDC(), STRETCH_DELETESCANS );
+ StretchBlt( mrParent.getHDC(),
+ (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
+ (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
+ hSrcDC,
+ (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
+ (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
+ nRop );
+ SetStretchBltMode( mrParent.getHDC(), nOldStretchMode );
+ }
+}
+
+void ImplCalcOutSideRgn( const RECT& rSrcRect,
+ int nLeft, int nTop, int nRight, int nBottom,
+ HRGN& rhInvalidateRgn )
+{
+ HRGN hTempRgn;
+
+ // calculate area outside the visible region
+ if ( rSrcRect.left < nLeft )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.top < nTop )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.right > nRight )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.bottom > nBottom )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+}
+
+void WinSalGraphicsImpl::copyArea( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 nFlags )
+{
+ bool bRestoreClipRgn = false;
+ HRGN hOldClipRgn = 0;
+ int nOldClipRgnType = ERROR;
+ HRGN hInvalidateRgn = 0;
+
+ // do we have to invalidate also the overlapping regions?
+ if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mrParent.isWindow() )
+ {
+ // compute and invalidate those parts that were either off-screen or covered by other windows
+ // while performing the above BitBlt
+ // those regions then have to be invalidated as they contain useless/wrong data
+ RECT aSrcRect;
+ RECT aClipRect;
+ RECT aTempRect;
+ RECT aTempRect2;
+ HRGN hTempRgn;
+ HWND hWnd;
+
+ // restrict srcRect to this window (calc intersection)
+ aSrcRect.left = (int)nSrcX;
+ aSrcRect.top = (int)nSrcY;
+ aSrcRect.right = aSrcRect.left+(int)nSrcWidth;
+ aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight;
+ GetClientRect( mrParent.gethWnd(), &aClipRect );
+ if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) )
+ {
+ // transform srcRect to screen coordinates
+ POINT aPt;
+ aPt.x = 0;
+ aPt.y = 0;
+ ClientToScreen( mrParent.gethWnd(), &aPt );
+ aSrcRect.left += aPt.x;
+ aSrcRect.top += aPt.y;
+ aSrcRect.right += aPt.x;
+ aSrcRect.bottom += aPt.y;
+ hInvalidateRgn = 0;
+
+ // compute the parts that are off screen (ie invisible)
+ RECT theScreen;
+ ImplSalGetWorkArea( NULL, &theScreen, NULL ); // find the screen area taking multiple monitors into account
+ ImplCalcOutSideRgn( aSrcRect, theScreen.left, theScreen.top, theScreen.right, theScreen.bottom, hInvalidateRgn );
+
+ // calculate regions that are covered by other windows
+ HRGN hTempRgn2 = 0;
+ HWND hWndTopWindow = mrParent.gethWnd();
+ // Find the TopLevel Window, because only Windows which are in
+ // in the foreground of our TopLevel window must be considered
+ if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD )
+ {
+ RECT aTempRect3 = aSrcRect;
+ do
+ {
+ hWndTopWindow = ::GetParent( hWndTopWindow );
+
+ // Test if the Parent clips our window
+ GetClientRect( hWndTopWindow, &aTempRect );
+ POINT aPt2;
+ aPt2.x = 0;
+ aPt2.y = 0;
+ ClientToScreen( hWndTopWindow, &aPt2 );
+ aTempRect.left += aPt2.x;
+ aTempRect.top += aPt2.y;
+ aTempRect.right += aPt2.x;
+ aTempRect.bottom += aPt2.y;
+ IntersectRect( &aTempRect3, &aTempRect3, &aTempRect );
+ }
+ while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD );
+
+ // If one or more Parents clip our window, than we must
+ // calculate the outside area
+ if ( !EqualRect( &aSrcRect, &aTempRect3 ) )
+ {
+ ImplCalcOutSideRgn( aSrcRect,
+ aTempRect3.left, aTempRect3.top,
+ aTempRect3.right, aTempRect3.bottom,
+ hInvalidateRgn );
+ }
+ }
+ // retrieve the top-most (z-order) child window
+ hWnd = GetWindow( GetDesktopWindow(), GW_CHILD );
+ while ( hWnd )
+ {
+ if ( hWnd == hWndTopWindow )
+ break;
+ if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) )
+ {
+ GetWindowRect( hWnd, &aTempRect );
+ if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) )
+ {
+ // hWnd covers part or all of aSrcRect
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect );
+
+ // get full bounding box of hWnd
+ hTempRgn = CreateRectRgnIndirect( &aTempRect );
+
+ // get region of hWnd (the window may be shaped)
+ if ( !hTempRgn2 )
+ hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 );
+ int nRgnType = GetWindowRgn( hWnd, hTempRgn2 );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ // convert window region to screen coordinates
+ OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top );
+ // and intersect with the window's bounding box
+ CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND );
+ }
+ // finally compute that part of aSrcRect which is not covered by any parts of hWnd
+ CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ }
+ // retrieve the next window in the z-order, i.e. the window below hwnd
+ hWnd = GetWindow( hWnd, GW_HWNDNEXT );
+ }
+ if ( hTempRgn2 )
+ DeleteRegion( hTempRgn2 );
+ if ( hInvalidateRgn )
+ {
+ // hInvalidateRgn contains the fully visible parts of the original srcRect
+ hTempRgn = CreateRectRgnIndirect( &aSrcRect );
+ // substract it from the original rect to get the occluded parts
+ int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ // move the occluded parts to the destination pos
+ int nOffX = (int)(nDestX-nSrcX);
+ int nOffY = (int)(nDestY-nSrcY);
+ OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y );
+
+ // by excluding hInvalidateRgn from the system's clip region
+ // we will prevent bitblt from copying useless data
+ // epsecially now shadows from overlapping windows will appear (#i36344)
+ hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 );
+ nOldClipRgnType = GetClipRgn( mrParent.getHDC(), hOldClipRgn );
+
+ bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate
+ ExtSelectClipRgn( mrParent.getHDC(), hInvalidateRgn, RGN_DIFF );
+ }
+ }
+ }
+ }
+
+ BitBlt( mrParent.getHDC(),
+ (int)nDestX, (int)nDestY,
+ (int)nSrcWidth, (int)nSrcHeight,
+ mrParent.getHDC(),
+ (int)nSrcX, (int)nSrcY,
+ SRCCOPY );
+
+ if( bRestoreClipRgn )
+ {
+ // restore old clip region
+ if( nOldClipRgnType != ERROR )
+ SelectClipRgn( mrParent.getHDC(), hOldClipRgn);
+ DeleteRegion( hOldClipRgn );
+
+ // invalidate regions that were not copied
+ bool bInvalidate = true;
+
+ // Combine Invalidate vcl::Region with existing ClipRegion
+ HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 );
+ if ( GetClipRgn( mrParent.getHDC(), hTempRgn ) == 1 )
+ {
+ int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND );
+ if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) )
+ bInvalidate = false;
+ }
+ DeleteRegion( hTempRgn );
+
+ if ( bInvalidate )
+ {
+ InvalidateRgn( mrParent.gethWnd(), hInvalidateRgn, TRUE );
+ // here we only initiate an update if this is the MainThread,
+ // so that there is no deadlock when handling the Paint event,
+ // as the SolarMutex is already held by this Thread
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId == nCurThreadId )
+ UpdateWindow( mrParent.gethWnd() );
+ }
+
+ DeleteRegion( hInvalidateRgn );
+ }
+
+}
+
+namespace {
+
+void ImplDrawBitmap( HDC hDC, const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap,
+ bool bPrinter, int nDrawMode )
+{
+ if( hDC )
+ {
+ HGLOBAL hDrawDIB;
+ HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
+ WinSalBitmap* pTmpSalBmp = NULL;
+ bool bPrintDDB = ( bPrinter && hDrawDDB );
+
+ if( bPrintDDB )
+ {
+ pTmpSalBmp = new WinSalBitmap;
+ pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
+ hDrawDIB = pTmpSalBmp->ImplGethDIB();
+ }
+ else
+ hDrawDIB = rSalBitmap.ImplGethDIB();
+
+ if( hDrawDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ StretchDIBits( hDC,
+ (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
+ (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
+ (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY),
+ (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
+ pBits, pBI, DIB_RGB_COLORS, nDrawMode );
+
+ GlobalUnlock( hDrawDIB );
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+ else if( hDrawDDB && !bPrintDDB )
+ {
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB );
+ COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF);
+ COLORREF nOldTextColor = RGB(0,0,0);
+ bool bMono = ( rSalBitmap.GetBitCount() == 1 );
+
+ if( bMono )
+ {
+ COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF );
+ COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 );
+ //fdo#33455 handle 1 bit depth pngs with palette entries
+ //to set fore/back colors
+ if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(true))
+ {
+ const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
+ if (rPalette.GetEntryCount() == 2)
+ {
+ SalColor nCol;
+ nCol = ImplColorToSal(rPalette[0]);
+ nTextColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
+ nCol = ImplColorToSal(rPalette[1]);
+ nBkColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
+ }
+ }
+ nOldBkColor = SetBkColor( hDC, nBkColor );
+ nOldTextColor = ::SetTextColor( hDC, nTextColor );
+ }
+
+ if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
+ (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
+ {
+ BitBlt( hDC,
+ (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
+ (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
+ hBmpDC,
+ (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
+ nDrawMode );
+ }
+ else
+ {
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ StretchBlt( hDC,
+ (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
+ (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
+ hBmpDC,
+ (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
+ (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
+ nDrawMode );
+
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+
+ if( bMono )
+ {
+ SetBkColor( hDC, nOldBkColor );
+ ::SetTextColor( hDC, nOldTextColor );
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_DRAW );
+ }
+
+ if( bPrintDDB )
+ delete pTmpSalBmp;
+ }
+}
+
+}
+
+void WinSalGraphicsImpl::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
+{
+ bool bTryDirectPaint(!mrParent.isPrinter() && !mbXORMode);
+
+ if(bTryDirectPaint)
+ {
+ // only paint direct when no scaling and no MapMode, else the
+ // more expensive conversions may be done for short-time Bitmap/BitmapEx
+ // used for buffering only
+ if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
+ {
+ bTryDirectPaint = false;
+ }
+ }
+
+ // try to draw using GdiPlus directly
+ if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap))
+ {
+ return;
+ }
+
+ // fall back old stuff
+ ImplDrawBitmap(mrParent.getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap),
+ mrParent.isPrinter(),
+ mbXORMode ? SRCINVERT : SRCCOPY );
+}
+
+void WinSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry,
+ const SalBitmap& rSSalBitmap,
+ SalColor nTransparentColor )
+{
+ DBG_ASSERT( !mrParent.isPrinter(), "No transparency print possible!" );
+
+ const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
+
+ WinSalBitmap* pMask = new WinSalBitmap;
+ const Point aPoint;
+ const Size aSize( rSalBitmap.GetSize() );
+ HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap );
+ const BYTE cRed = SALCOLOR_RED( nTransparentColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor );
+
+ if( rSalBitmap.ImplGethDDB() )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+ else
+ {
+ WinSalBitmap* pTmpSalBmp = new WinSalBitmap;
+
+ if( pTmpSalBmp->Create( rSalBitmap, &mrParent ) )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+
+ delete pTmpSalBmp;
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE )
+ if( pMask->Create( hMaskBitmap, FALSE, FALSE ) )
+ drawBitmap( rPosAry, rSalBitmap, *pMask );
+
+ delete pMask;
+}
+
+void WinSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry,
+ const SalBitmap& rSSalBitmap,
+ const SalBitmap& rSTransparentBitmap )
+{
+ DBG_ASSERT( !mrParent.isPrinter(), "No transparency print possible!" );
+ bool bTryDirectPaint(!mrParent.isPrinter() && !mbXORMode);
+
+ if(bTryDirectPaint)
+ {
+ // only paint direct when no scaling and no MapMode, else the
+ // more expensive conversions may be done for short-time Bitmap/BitmapEx
+ // used for buffering only
+ if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
+ {
+ bTryDirectPaint = false;
+ }
+ }
+
+ // try to draw using GdiPlus directly
+ if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap))
+ {
+ return;
+ }
+
+ const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
+ const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap);
+
+ SalTwoRect aPosAry = rPosAry;
+ int nDstX = (int)aPosAry.mnDestX;
+ int nDstY = (int)aPosAry.mnDestY;
+ int nDstWidth = (int)aPosAry.mnDestWidth;
+ int nDstHeight = (int)aPosAry.mnDestHeight;
+ HDC hDC = mrParent.getHDC();
+ HBITMAP hMemBitmap = 0;
+ HBITMAP hMaskBitmap = 0;
+
+ if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) )
+ {
+ hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ }
+
+ HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap );
+
+ aPosAry.mnDestX = aPosAry.mnDestY = 0;
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY );
+
+ // WIN/WNT seems to have a minor problem mapping the correct color of the
+ // mask to the palette if we draw the DIB directly ==> draw DDB
+ if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
+ {
+ WinSalBitmap aTmp;
+
+ if( aTmp.Create( rTransparentBitmap, &mrParent ) )
+ ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY );
+ }
+ else
+ ImplDrawBitmap( hMaskDC, aPosAry, rTransparentBitmap, FALSE, SRCCOPY );
+
+ // now MemDC contains background, MaskDC the transparency mask
+
+ // #105055# Respect XOR mode
+ if( mbXORMode )
+ {
+ ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE );
+ // now MaskDC contains the bitmap area with black background
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT );
+ // now MemDC contains background XORed bitmap area ontop
+ }
+ else
+ {
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND );
+ // now MemDC contains background with masked-out bitmap area
+ ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE );
+ // now MaskDC contains the bitmap area with black background
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT );
+ // now MemDC contains background and bitmap merged together
+ }
+ // copy to output DC
+ BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY );
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+
+ // hMemBitmap != 0 ==> hMaskBitmap != 0
+ if( hMemBitmap )
+ {
+ DeleteObject( hMemBitmap );
+ DeleteObject( hMaskBitmap );
+ }
+}
+
+bool WinSalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
+ long nHeight, sal_uInt8 nTransparency )
+{
+ if( mbPen || !mbBrush || mbXORMode )
+ return false; // can only perform solid fills without XOR.
+
+ HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 );
+ SetPixel( hMemDC, (int)0, (int)0, mnBrushColor );
+
+ BLENDFUNCTION aFunc = {
+ AC_SRC_OVER,
+ 0,
+ sal::static_int_cast<sal_uInt8>(255 - 255L*nTransparency/100),
+ 0
+ };
+
+ // hMemDC contains a 1x1 bitmap of the right color - stretch-blit
+ // that to dest hdc
+ bool bRet = AlphaBlend( mrParent.getHDC(), nX, nY, nWidth, nHeight,
+ hMemDC, 0,0,1,1,
+ aFunc ) == TRUE;
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ return bRet;
+}
+
+void WinSalGraphicsImpl::drawMask( const SalTwoRect& rPosAry,
+ const SalBitmap& rSSalBitmap,
+ SalColor nMaskColor )
+{
+ DBG_ASSERT( !mrParent.isPrinter(), "No transparency print possible!" );
+
+ const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
+
+ SalTwoRect aPosAry = rPosAry;
+ const BYTE cRed = SALCOLOR_RED( nMaskColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nMaskColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nMaskColor );
+ HDC hDC = mrParent.getHDC();
+ HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) );
+ HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush );
+
+ // WIN/WNT seems to have a minor problem mapping the correct color of the
+ // mask to the palette if we draw the DIB directly ==> draw DDB
+ if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
+ {
+ WinSalBitmap aTmp;
+
+ if( aTmp.Create( rSalBitmap, &mrParent ) )
+ ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL );
+ }
+ else
+ ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
+
+ SelectBrush( hDC, hOldBrush );
+ DeleteBrush( hMaskBrush );
+}
+
+SalBitmap* WinSalGraphicsImpl::getBitmap( long nX, long nY, long nDX, long nDY )
+{
+ DBG_ASSERT( !mrParent.isPrinter(), "No ::GetBitmap() from printer possible!" );
+
+ WinSalBitmap* pSalBitmap = NULL;
+
+ nDX = labs( nDX );
+ nDY = labs( nDY );
+
+ HDC hDC = mrParent.getHDC();
+ HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
+ bool bRet;
+
+ bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE;
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ if( bRet )
+ {
+ pSalBitmap = new WinSalBitmap;
+
+ if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
+ {
+ delete pSalBitmap;
+ pSalBitmap = NULL;
+ }
+ }
+ else
+ {
+ // #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers)
+ DeleteBitmap( hBmpBitmap );
+ }
+
+ return pSalBitmap;
+}
+
+SalColor WinSalGraphicsImpl::getPixel( long nX, long nY )
+{
+ COLORREF aWinCol = ::GetPixel( mrParent.getHDC(), (int) nX, (int) nY );
+
+ if ( CLR_INVALID == aWinCol )
+ return MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ return MAKE_SALCOLOR( GetRValue( aWinCol ),
+ GetGValue( aWinCol ),
+ GetBValue( aWinCol ) );
+}
+
+void WinSalGraphicsImpl::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
+{
+ if ( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ HPEN hDotPen = CreatePen( PS_DOT, 0, 0 );
+ HPEN hOldPen = SelectPen( mrParent.getHDC(), hDotPen );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), GetStockBrush( NULL_BRUSH ) );
+ int nOldROP = SetROP2( mrParent.getHDC(), R2_NOT );
+
+ WIN_Rectangle( mrParent.getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+
+ SetROP2( mrParent.getHDC(), nOldROP );
+ SelectPen( mrParent.getHDC(), hOldPen );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ DeletePen( hDotPen );
+ }
+ else if ( nFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ COLORREF nOldTextColor = ::SetTextColor( mrParent.getHDC(), 0 );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), pSalData->mh50Brush );
+ PatBlt( mrParent.getHDC(), nX, nY, nWidth, nHeight, PATINVERT );
+ ::SetTextColor( mrParent.getHDC(), nOldTextColor );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ }
+ else
+ {
+ RECT aRect;
+ aRect.left = (int)nX;
+ aRect.top = (int)nY;
+ aRect.right = (int)nX+nWidth;
+ aRect.bottom = (int)nY+nHeight;
+ ::InvertRect( mrParent.getHDC(), &aRect );
+ }
+}
+
+void WinSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
+{
+ HPEN hPen;
+ HPEN hOldPen;
+ HBRUSH hBrush;
+ HBRUSH hOldBrush = 0;
+ COLORREF nOldTextColor RGB(0,0,0);
+ int nOldROP = SetROP2( mrParent.getHDC(), R2_NOT );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ hPen = CreatePen( PS_DOT, 0, 0 );
+ else
+ {
+
+ if ( nSalFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ hBrush = pSalData->mh50Brush;
+ }
+ else
+ hBrush = GetStockBrush( BLACK_BRUSH );
+
+ hPen = GetStockPen( NULL_PEN );
+ nOldTextColor = ::SetTextColor( mrParent.getHDC(), 0 );
+ hOldBrush = SelectBrush( mrParent.getHDC(), hBrush );
+ }
+ hOldPen = SelectPen( mrParent.getHDC(), hPen );
+
+ POINT* pWinPtAry;
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolyLine(): POINT != SalPoint" );
+
+ pWinPtAry = (POINT*)pPtAry;
+ // for Windows 95 and its maximum number of points
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ {
+ if ( !Polyline( mrParent.getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( mrParent.getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+ }
+ else
+ {
+ if ( !WIN_Polygon( mrParent.getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( mrParent.getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+ }
+
+ SetROP2( mrParent.getHDC(), nOldROP );
+ SelectPen( mrParent.getHDC(), hOldPen );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ DeletePen( hPen );
+ else
+ {
+ ::SetTextColor( mrParent.getHDC(), nOldTextColor );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ }
+}
+
+sal_uInt16 WinSalGraphicsImpl::GetBitCount() const
+{
+ return (sal_uInt16)GetDeviceCaps( mrParent.getHDC(), BITSPIXEL );
+}
+
+long WinSalGraphicsImpl::GetGraphicsWidth() const
+{
+ if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) )
+ {
+ WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() );
+ if( pFrame )
+ {
+ if( pFrame->maGeometry.nWidth )
+ return pFrame->maGeometry.nWidth;
+ else
+ {
+ // TODO: perhaps not needed, maGeometry should always be up-to-date
+ RECT aRect;
+ GetClientRect( mrParent.gethWnd(), &aRect );
+ return aRect.right;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void WinSalGraphicsImpl::ResetClipRegion()
+{
+ if ( mrParent.mhRegion )
+ {
+ DeleteRegion( mrParent.mhRegion );
+ mrParent.mhRegion = 0;
+ }
+
+ SelectClipRgn( mrParent.getHDC(), 0 );
+}
+
+bool WinSalGraphicsImpl::setClipRegion( const vcl::Region& i_rClip )
+{
+ if ( mrParent.mhRegion )
+ {
+ DeleteRegion( mrParent.mhRegion );
+ mrParent.mhRegion = 0;
+ }
+
+ bool bUsePolygon(i_rClip.HasPolyPolygonOrB2DPolyPolygon());
+ static bool bTryToAvoidPolygon(true);
+
+ // #i122149# try to avoid usage of tools::PolyPolygon ClipRegions when tools::PolyPolygon is no curve
+ // and only contains horizontal/vertical edges. In that case, use the fallback
+ // in GetRegionRectangles which will use vcl::Region::GetAsRegionBand() which will do
+ // the correct polygon-to-RegionBand transformation.
+ // Background is that when using the same Rectangle as rectangle or as Polygon
+ // clip region will lead to different results; the polygon-based one will be
+ // one pixel less to the right and down (see GDI docu for CreatePolygonRgn). This
+ // again is because of the polygon-nature and it's classic handling when filling.
+ // This also means that all cases which use a 'true' polygon-based incarnation of
+ // a vcl::Region should know what they do - it may lead to repaint errors.
+ if(bUsePolygon && bTryToAvoidPolygon)
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
+
+ if(!aPolyPolygon.areControlPointsUsed())
+ {
+ if(basegfx::tools::containsOnlyHorizontalAndVerticalEdges(aPolyPolygon))
+ {
+ bUsePolygon = false;
+ }
+ }
+ }
+
+ if(bUsePolygon)
+ {
+ // #i122149# check the comment above to know that this may lead to potential repaint
+ // problems. It may be solved (if needed) by scaling the polygon by one in X
+ // and Y. Currently the workaround to only use it if really unavoidable will
+ // solve most cases. When someone is really using polygon-based Regions he
+ // should know what he is doing.
+ // Added code to do that scaling to check if it works, testing it.
+ const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ if( nCount )
+ {
+ std::vector< POINT > aPolyPoints;
+ aPolyPoints.reserve( 1024 );
+ std::vector< INT > aPolyCounts( nCount, 0 );
+ basegfx::B2DHomMatrix aExpand;
+ static bool bExpandByOneInXandY(true);
+
+ if(bExpandByOneInXandY)
+ {
+ const basegfx::B2DRange aRangeS(aPolyPolygon.getB2DRange());
+ const basegfx::B2DRange aRangeT(aRangeS.getMinimum(), aRangeS.getMaximum() + basegfx::B2DTuple(1.0, 1.0));
+ aExpand = basegfx::B2DHomMatrix(basegfx::tools::createSourceRangeTargetRangeTransform(aRangeS, aRangeT));
+ }
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ const basegfx::B2DPolygon aPoly(
+ basegfx::tools::adaptiveSubdivideByDistance(
+ aPolyPolygon.getB2DPolygon(a),
+ 1));
+ const sal_uInt32 nPoints(aPoly.count());
+ aPolyCounts[a] = nPoints;
+
+ for( sal_uInt32 b = 0; b < nPoints; b++ )
+ {
+ basegfx::B2DPoint aPt(aPoly.getB2DPoint(b));
+
+ if(bExpandByOneInXandY)
+ {
+ aPt = aExpand * aPt;
+ }
+
+ POINT aPOINT;
+ // #i122149# do correct rounding
+ aPOINT.x = basegfx::fround(aPt.getX());
+ aPOINT.y = basegfx::fround(aPt.getY());
+ aPolyPoints.push_back( aPOINT );
+ }
+ }
+
+ mrParent.mhRegion = CreatePolyPolygonRgn( &aPolyPoints[0], &aPolyCounts[0], nCount, ALTERNATE );
+ }
+ }
+ else
+ {
+ RectangleVector aRectangles;
+ i_rClip.GetRegionRectangles(aRectangles);
+
+ sal_uLong nRectBufSize = sizeof(RECT)*aRectangles.size();
+ if ( aRectangles.size() < SAL_CLIPRECT_COUNT )
+ {
+ if ( !mrParent.mpStdClipRgnData )
+ mrParent.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ mrParent.mpClipRgnData = mrParent.mpStdClipRgnData;
+ }
+ else
+ mrParent.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ mrParent.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ mrParent.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ mrParent.mpClipRgnData->rdh.nCount = aRectangles.size();
+ mrParent.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ RECT* pBoundRect = &(mrParent.mpClipRgnData->rdh.rcBound);
+ SetRectEmpty( pBoundRect );
+ RECT* pNextClipRect = (RECT*)(&(mrParent.mpClipRgnData->Buffer));
+ bool bFirstClipRect = true;
+
+ for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
+ {
+ const long nW(aRectIter->GetWidth());
+ const long nH(aRectIter->GetHeight());
+
+ if(nW && nH)
+ {
+ const long nRight(aRectIter->Left() + nW);
+ const long nBottom(aRectIter->Top() + nH);
+
+ if(bFirstClipRect)
+ {
+ pBoundRect->left = aRectIter->Left();
+ pBoundRect->top = aRectIter->Top();
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ bFirstClipRect = false;
+ }
+ else
+ {
+ if(aRectIter->Left() < pBoundRect->left)
+ {
+ pBoundRect->left = (int)aRectIter->Left();
+ }
+
+ if(aRectIter->Top() < pBoundRect->top)
+ {
+ pBoundRect->top = (int)aRectIter->Top();
+ }
+
+ if(nRight > pBoundRect->right)
+ {
+ pBoundRect->right = (int)nRight;
+ }
+
+ if(nBottom > pBoundRect->bottom)
+ {
+ pBoundRect->bottom = (int)nBottom;
+ }
+ }
+
+ pNextClipRect->left = (int)aRectIter->Left();
+ pNextClipRect->top = (int)aRectIter->Top();
+ pNextClipRect->right = (int)nRight;
+ pNextClipRect->bottom = (int)nBottom;
+ pNextClipRect++;
+ }
+ else
+ {
+ mrParent.mpClipRgnData->rdh.nCount--;
+ mrParent.mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
+ }
+ }
+
+ // create clip region from ClipRgnData
+ if(0 == mrParent.mpClipRgnData->rdh.nCount)
+ {
+ // #i123585# region is empty; this may happen when e.g. a tools::PolyPolygon is given
+ // that contains no polygons or only empty ones (no width/height). This is
+ // perfectly fine and we are done, except setting it (see end of method)
+ }
+ else if(1 == mrParent.mpClipRgnData->rdh.nCount)
+ {
+ RECT* pRect = &(mrParent.mpClipRgnData->rdh.rcBound);
+ mrParent.mhRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else if(mrParent.mpClipRgnData->rdh.nCount > 1)
+ {
+ sal_uLong nSize = mrParent.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ mrParent.mhRegion = ExtCreateRegion( NULL, nSize, mrParent.mpClipRgnData );
+
+ // if ExtCreateRegion(...) is not supported
+ if( !mrParent.mhRegion )
+ {
+ RGNDATAHEADER* pHeader = (RGNDATAHEADER*) mrParent.mpClipRgnData;
+
+ if( pHeader->nCount )
+ {
+ RECT* pRect = (RECT*) mrParent.mpClipRgnData->Buffer;
+ mrParent.mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ pRect++;
+
+ for( sal_uLong n = 1; n < pHeader->nCount; n++, pRect++ )
+ {
+ HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ CombineRgn( mrParent.mhRegion, mrParent.mhRegion, hRgn, RGN_OR );
+ DeleteRegion( hRgn );
+ }
+ }
+ }
+
+ if ( mrParent.mpClipRgnData != mrParent.mpStdClipRgnData )
+ delete [] mrParent.mpClipRgnData;
+ }
+ }
+
+ if( mrParent.mhRegion )
+ {
+ SelectClipRgn( mrParent.getHDC(), mrParent.mhRegion );
+
+ // debug code if you weant to check range of the newly applied ClipRegion
+ //RECT aBound;
+ //const int aRegionType = GetRgnBox(mrParent.mhRegion, &aBound);
+
+ //bool bBla = true;
+ }
+ else
+ {
+ // #i123585# See above, this is a valid case, execute it
+ SelectClipRgn( mrParent.getHDC(), 0 );
+ }
+
+ // #i123585# retval no longer dependent of mrParent.mhRegion, see TaskId comments above
+ return true;
+}
+
+void WinSalGraphicsImpl::SetLineColor()
+{
+ // create and select new pen
+ HPEN hNewPen = GetStockPen( NULL_PEN );
+ HPEN hOldPen = SelectPen( mrParent.getHDC(), hNewPen );
+
+ // destroy or save old pen
+ if ( mhPen )
+ {
+ if ( !mbStockPen )
+ DeletePen( mhPen );
+ }
+ else
+ mrParent.mhDefPen = hOldPen;
+
+ // set new data
+ mhPen = hNewPen;
+ mbPen = FALSE;
+ mbStockPen = TRUE;
+}
+
+void WinSalGraphicsImpl::SetLineColor( SalColor nSalColor )
+{
+ maLineColor = nSalColor;
+ COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ HPEN hNewPen = 0;
+ bool bStockPen = FALSE;
+
+ // search for stock pen (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !mrParent.isPrinter() )
+ {
+ SalData* pSalData = GetSalData();
+ for ( sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++ )
+ {
+ if ( nPenColor == pSalData->maStockPenColorAry[i] )
+ {
+ hNewPen = pSalData->mhStockPenAry[i];
+ bStockPen = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new pen
+ if ( !hNewPen )
+ {
+ if ( !mrParent.isPrinter() )
+ {
+ if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
+ nPenColor = PALRGB_TO_RGB( nPenColor );
+ }
+
+ hNewPen = CreatePen( PS_SOLID, mrParent.mnPenWidth, nPenColor );
+ bStockPen = FALSE;
+ }
+
+ // select new pen
+ HPEN hOldPen = SelectPen( mrParent.getHDC(), hNewPen );
+
+ // destroy or save old pen
+ if ( mhPen )
+ {
+ if ( !mbStockPen )
+ DeletePen( mhPen );
+ }
+ else
+ mrParent.mhDefPen = hOldPen;
+
+ // set new data
+ mnPenColor = nPenColor;
+ mhPen = hNewPen;
+ mbPen = TRUE;
+ mbStockPen = bStockPen;
+}
+
+void WinSalGraphicsImpl::SetFillColor()
+{
+ // create and select new brush
+ HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hNewBrush );
+
+ // destroy or save old brush
+ if ( mhBrush )
+ {
+ if ( !mbStockBrush )
+ DeleteBrush( mhBrush );
+ }
+ else
+ mrParent.mhDefBrush = hOldBrush;
+
+ // set new data
+ mhBrush = hNewBrush;
+ mbBrush = FALSE;
+ mbStockBrush = TRUE;
+}
+
+void WinSalGraphicsImpl::SetFillColor( SalColor nSalColor )
+{
+ maFillColor = nSalColor;
+ SalData* pSalData = GetSalData();
+ BYTE nRed = SALCOLOR_RED( nSalColor );
+ BYTE nGreen = SALCOLOR_GREEN( nSalColor );
+ BYTE nBlue = SALCOLOR_BLUE( nSalColor );
+ COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
+ HBRUSH hNewBrush = 0;
+ bool bStockBrush = FALSE;
+
+ // search for stock brush (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !mrParent.isPrinter() )
+ {
+ for ( sal_uInt16 i = 0; i < pSalData->mnStockBrushCount; i++ )
+ {
+ if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
+ {
+ hNewBrush = pSalData->mhStockBrushAry[i];
+ bStockBrush = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new brush
+ if ( !hNewBrush )
+ {
+ if ( mrParent.isPrinter() || !pSalData->mhDitherDIB )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for( long nY = 0L; nY < 8L; nY++ )
+ {
+ for( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither16Bit[ nY ][ nX ];
+ *pTmp++ = DMAP( nBlue, nThres );
+ *pTmp++ = DMAP( nGreen, nThres );
+ *pTmp++ = DMAP( nRed, nThres );
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
+ }
+ else if ( ImplIsSysColorEntry( nSalColor ) )
+ {
+ nBrushColor = PALRGB_TO_RGB( nBrushColor );
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ }
+ else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for ( long nY = 0L; nY < 8L; nY++ )
+ {
+ for ( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither8Bit[ nY ][ nX ];
+ *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
+ pTmp++;
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
+ }
+ }
+
+ bStockBrush = FALSE;
+ }
+
+ // select new brush
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hNewBrush );
+
+ // destroy or save old brush
+ if ( mhBrush )
+ {
+ if ( !mbStockBrush )
+ DeleteBrush( mhBrush );
+ }
+ else
+ mrParent.mhDefBrush = hOldBrush;
+
+ // set new data
+ mnBrushColor = nBrushColor;
+ mhBrush = hNewBrush;
+ mbBrush = TRUE;
+ mbStockBrush = bStockBrush;
+}
+
+void WinSalGraphicsImpl::SetXORMode( bool bSet, bool )
+{
+ mbXORMode = bSet;
+ ::SetROP2( mrParent.getHDC(), bSet ? R2_XORPEN : R2_COPYPEN );
+}
+
+void WinSalGraphicsImpl::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+void WinSalGraphicsImpl::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+void WinSalGraphicsImpl::drawPixel( long nX, long nY )
+{
+ if ( mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hBrush );
+ PatBlt( mrParent.getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( mrParent.getHDC(), (int)nX, (int)nY, mnPenColor );
+}
+
+void WinSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if ( !mrParent.isPrinter() &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ nCol = PALRGB_TO_RGB( nCol );
+
+ if ( mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( nCol );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hBrush );
+ PatBlt( mrParent.getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ ::SetPixel( mrParent.getHDC(), (int)nX, (int)nY, nCol );
+}
+
+void WinSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ MoveToEx( mrParent.getHDC(), (int)nX1, (int)nY1, NULL );
+
+ // we must paint the endpoint
+ int bPaintEnd = TRUE;
+ if ( nX1 == nX2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nY1 <= nY2 )
+ nY2++;
+ else
+ nY2--;
+ }
+ if ( nY1 == nY2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nX1 <= nX2 )
+ nX2++;
+ else
+ nX2--;
+ }
+
+ LineTo( mrParent.getHDC(), (int)nX2, (int)nY2 );
+
+ if ( bPaintEnd && !mrParent.isPrinter() )
+ {
+ if ( mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hBrush );
+ PatBlt( mrParent.getHDC(), (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( mrParent.getHDC(), (int)nX2, (int)nY2, mnPenColor );
+ }
+}
+
+void WinSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( !mbPen )
+ {
+ if ( !mrParent.isPrinter() )
+ {
+ PatBlt( mrParent.getHDC(), (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ mbXORMode ? PATINVERT : PATCOPY );
+ }
+ else
+ {
+ RECT aWinRect;
+ aWinRect.left = nX;
+ aWinRect.top = nY;
+ aWinRect.right = nX+nWidth;
+ aWinRect.bottom = nY+nHeight;
+ ::FillRect( mrParent.getHDC(), &aWinRect, mhBrush );
+ }
+ }
+ else
+ WIN_Rectangle( mrParent.getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+}
+
+void WinSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolyLine(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+
+ // we assume there are at least 2 points (Polyline requres at least 2 point, see MSDN)
+ // we must paint the endpoint for last line
+ BOOL bPaintEnd = TRUE;
+ if ( pWinPtAry[nPoints-2].x == pWinPtAry[nPoints-1].x )
+ {
+ bPaintEnd = FALSE;
+ if ( pWinPtAry[nPoints-2].y <= pWinPtAry[nPoints-1].y )
+ pWinPtAry[nPoints-1].y++;
+ else
+ pWinPtAry[nPoints-1].y--;
+ }
+ if ( pWinPtAry[nPoints-2].y == pWinPtAry[nPoints-1].y )
+ {
+ bPaintEnd = FALSE;
+ if ( pWinPtAry[nPoints-2].x <= pWinPtAry[nPoints-1].x )
+ pWinPtAry[nPoints-1].x++;
+ else
+ pWinPtAry[nPoints-1].x--;
+ }
+
+ // for Windows 95 and its maximum number of points
+ if ( !Polyline( mrParent.getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( mrParent.getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+
+ if ( bPaintEnd && !mrParent.isPrinter() )
+ {
+ if ( mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( mrParent.getHDC(), hBrush );
+ PatBlt( mrParent.getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), (int)1, (int)1, PATINVERT );
+ SelectBrush( mrParent.getHDC(), hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( mrParent.getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), mnPenColor );
+ }
+}
+
+void WinSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolygon(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // for Windows 95 and its maximum number of points
+ if ( !WIN_Polygon( mrParent.getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( mrParent.getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+}
+
+void WinSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
+ UINT* pWinPointAry;
+ UINT nPolyPolyPoints = 0;
+ UINT nPoints;
+ UINT i;
+
+ if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
+ pWinPointAry = aWinPointAry;
+ else
+ pWinPointAry = new UINT[nPoly];
+
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = (UINT)pPoints[i]+1;
+ pWinPointAry[i] = nPoints;
+ nPolyPolyPoints += nPoints;
+ }
+
+ POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
+ POINT* pWinPointAryAry;
+ if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
+ pWinPointAryAry = aWinPointAryAry;
+ else
+ pWinPointAryAry = new POINT[nPolyPolyPoints];
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolyPolygon(): POINT != SalPoint" );
+ const SalPoint* pPolyAry;
+ UINT n = 0;
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = pWinPointAry[i];
+ pPolyAry = pPtAry[i];
+ memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
+ pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
+ n += nPoints;
+ }
+
+ if ( !WIN_PolyPolygon( mrParent.getHDC(), pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
+ (nPolyPolyPoints > MAX_64KSALPOINTS) )
+ {
+ nPolyPolyPoints = 0;
+ nPoly = 0;
+ do
+ {
+ nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
+ nPoly++;
+ }
+ while ( nPolyPolyPoints < MAX_64KSALPOINTS );
+ nPoly--;
+ if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
+ pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
+ if ( nPoly == 1 )
+ WIN_Polygon( mrParent.getHDC(), pWinPointAryAry, *pWinPointAry );
+ else
+ WIN_PolyPolygon( mrParent.getHDC(), pWinPointAryAry, (int*)pWinPointAry, nPoly );
+ }
+
+ if ( pWinPointAry != aWinPointAry )
+ delete [] pWinPointAry;
+ if ( pWinPointAryAry != aWinPointAryAry )
+ delete [] pWinPointAryAry;
+}
+
+bool WinSalGraphicsImpl::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
+{
+#ifdef USE_GDI_BEZIERS
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolyLineBezier(): POINT != SalPoint" );
+
+ ImplRenderPath( mrParent.getHDC(), nPoints, pPtAry, pFlgAry );
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool WinSalGraphicsImpl::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
+{
+#ifdef USE_GDI_BEZIERS
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolygonBezier(): POINT != SalPoint" );
+
+ POINT aStackAry1[SAL_POLY_STACKBUF];
+ BYTE aStackAry2[SAL_POLY_STACKBUF];
+ POINT* pWinPointAry;
+ BYTE* pWinFlagAry;
+ if( nPoints > SAL_POLY_STACKBUF )
+ {
+ pWinPointAry = new POINT[ nPoints ];
+ pWinFlagAry = new BYTE[ nPoints ];
+ }
+ else
+ {
+ pWinPointAry = aStackAry1;
+ pWinFlagAry = aStackAry2;
+ }
+
+ sal_uInt32 nPoints_i32(nPoints);
+ ImplPreparePolyDraw(true, 1, &nPoints_i32, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry);
+
+ bool bRet( false );
+
+ if( BeginPath( mrParent.getHDC() ) )
+ {
+ PolyDraw(mrParent.getHDC(), pWinPointAry, pWinFlagAry, nPoints);
+
+ if( EndPath( mrParent.getHDC() ) )
+ {
+ if( StrokeAndFillPath( mrParent.getHDC() ) )
+ bRet = true;
+ }
+ }
+
+ if( pWinPointAry != aStackAry1 )
+ {
+ delete [] pWinPointAry;
+ delete [] pWinFlagAry;
+ }
+
+ return bRet;
+#else
+ return false;
+#endif
+}
+
+bool WinSalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
+{
+#ifdef USE_GDI_BEZIERS
+ // for NT, we can handover the array directly
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "WinSalGraphicsImpl::DrawPolyPolygonBezier(): POINT != SalPoint" );
+
+ sal_uLong nCurrPoly, nTotalPoints;
+ const sal_uInt32* pCurrPoints = pPoints;
+ for( nCurrPoly=0, nTotalPoints=0; nCurrPoly<nPoly; ++nCurrPoly )
+ nTotalPoints += *pCurrPoints++;
+
+ POINT aStackAry1[SAL_POLY_STACKBUF];
+ BYTE aStackAry2[SAL_POLY_STACKBUF];
+ POINT* pWinPointAry;
+ BYTE* pWinFlagAry;
+ if( nTotalPoints > SAL_POLY_STACKBUF )
+ {
+ pWinPointAry = new POINT[ nTotalPoints ];
+ pWinFlagAry = new BYTE[ nTotalPoints ];
+ }
+ else
+ {
+ pWinPointAry = aStackAry1;
+ pWinFlagAry = aStackAry2;
+ }
+
+ ImplPreparePolyDraw(true, nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry);
+
+ bool bRet( false );
+
+ if( BeginPath( mrParent.getHDC() ) )
+ {
+ PolyDraw(mrParent.getHDC(), pWinPointAry, pWinFlagAry, nTotalPoints);
+
+ if( EndPath( mrParent.getHDC() ) )
+ {
+ if( StrokeAndFillPath( mrParent.getHDC() ) )
+ bRet = true;
+ }
+ }
+
+ if( pWinPointAry != aStackAry1 )
+ {
+ delete [] pWinPointAry;
+ delete [] pWinFlagAry;
+ }
+
+ return bRet;
+#else
+ return false;
+#endif
+}
+
+void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
+{
+ sal_uInt32 nCount(rPolygon.count());
+
+ if(nCount)
+ {
+ const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
+ const bool bControls(rPolygon.areControlPointsUsed());
+ basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
+
+ for(sal_uInt32 a(0); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex((a + 1) % nCount);
+ const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
+
+ if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
+ {
+ const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
+ const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
+
+ Gdiplus::DllExports::GdipAddPathBezier(pPath,
+ aCurr.getX(), aCurr.getY(),
+ aCa.getX(), aCa.getY(),
+ aCb.getX(), aCb.getY(),
+ aNext.getX(), aNext.getY());
+ }
+ else
+ {
+ Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
+ }
+
+ if(a + 1 < nEdgeCount)
+ {
+ aCurr = aNext;
+
+ if(bNoLineJoin)
+ {
+ Gdiplus::DllExports::GdipStartPathFigure(pPath);
+ }
+ }
+ }
+ }
+}
+
+void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
+{
+ sal_uInt32 nCount(rPolygon.count());
+
+ if(nCount)
+ {
+ const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
+ const bool bControls(rPolygon.areControlPointsUsed());
+ basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
+
+ for(sal_uInt32 a(0); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex((a + 1) % nCount);
+ const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
+
+ if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
+ {
+ const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
+ const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
+
+ Gdiplus::DllExports::GdipAddPathBezier(
+ pPath,
+ aCurr.getX(), aCurr.getY(),
+ aCa.getX(), aCa.getY(),
+ aCb.getX(), aCb.getY(),
+ aNext.getX(), aNext.getY());
+ }
+ else
+ {
+ Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
+ }
+
+ if(a + 1 < nEdgeCount)
+ {
+ aCurr = aNext;
+
+ if(bNoLineJoin)
+ {
+ Gdiplus::DllExports::GdipStartPathFigure(pPath);
+ }
+ }
+ }
+ }
+}
+
+bool WinSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
+{
+ const sal_uInt32 nCount(rPolyPolygon.count());
+
+ if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
+ {
+ Gdiplus::GpGraphics *pGraphics = NULL;
+ Gdiplus::DllExports::GdipCreateFromHDC(mrParent.getHDC(), &pGraphics);
+ const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
+ Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
+ Gdiplus::GpSolidFill *pTestBrush;
+ Gdiplus::DllExports::GdipCreateSolidFill(aTestColor.GetValue(), &pTestBrush);
+ Gdiplus::GpPath *pPath = NULL;
+ Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ if(0 != a)
+ {
+ Gdiplus::DllExports::GdipStartPathFigure(pPath); // #i101491# not needed for first run
+ }
+
+ impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolyPolygon.getB2DPolygon(a), false);
+ Gdiplus::DllExports::GdipClosePathFigure(pPath);
+ }
+
+ if(mrParent.getAntiAliasB2DDraw())
+ {
+ Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
+ }
+ else
+ {
+ Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
+ }
+
+ if(mrParent.isPrinter())
+ {
+ // #i121591#
+ // Normally GdiPlus should not be used for printing at all since printers cannot
+ // print transparent filled polygon geometry and normally this does not happen
+ // since OutputDevice::RemoveTransparenciesFromMetaFile is used as preparation
+ // and no transparent parts should remain for printing. But this can be overridden
+ // by the user and thus happens. This call can only come (currently) from
+ // OutputDevice::DrawTransparent, see comments there with the same TaskID.
+ // If it is used, the mapping for the printer is wrong and needs to be corrected. I
+ // checked that there is *no* transformation set and estimated that a stable factor
+ // dependent of the printer's DPI is used. Create and set a transformation here to
+ // correct this.
+ Gdiplus::REAL aDpiX;
+ Gdiplus::DllExports::GdipGetDpiX(pGraphics, &aDpiX);
+ Gdiplus::REAL aDpiY;
+ Gdiplus::DllExports::GdipGetDpiY(pGraphics, &aDpiY);
+
+ Gdiplus::DllExports::GdipResetWorldTransform(pGraphics);
+ Gdiplus::DllExports::GdipScaleWorldTransform(pGraphics, Gdiplus::REAL(100.0) / aDpiX, Gdiplus::REAL(100.0) / aDpiY, Gdiplus::MatrixOrderAppend);
+ }
+
+ Gdiplus::DllExports::GdipFillPath(pGraphics, pTestBrush, pPath);
+
+ Gdiplus::DllExports::GdipDeletePath(pPath);
+ Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
+ }
+
+ return true;
+}
+
+bool WinSalGraphicsImpl::drawPolyLine(
+ const basegfx::B2DPolygon& rPolygon,
+ double fTransparency,
+ const basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin eLineJoin,
+ com::sun::star::drawing::LineCap eLineCap)
+{
+ const sal_uInt32 nCount(rPolygon.count());
+
+ if(mbPen && nCount)
+ {
+ Gdiplus::GpGraphics *pGraphics = NULL;
+ Gdiplus::DllExports::GdipCreateFromHDC(mrParent.getHDC(), &pGraphics);
+ const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
+ Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
+ Gdiplus::GpPen *pTestPen = NULL;
+ Gdiplus::DllExports::GdipCreatePen1(aTestColor.GetValue(), Gdiplus::REAL(rLineWidths.getX()), Gdiplus::UnitWorld, &pTestPen);
+ Gdiplus::GpPath *pPath;
+ Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
+ bool bNoLineJoin(false);
+
+ switch(eLineJoin)
+ {
+ default : // basegfx::B2DLINEJOIN_NONE :
+ {
+ if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
+ {
+ bNoLineJoin = true;
+ }
+ break;
+ }
+ case basegfx::B2DLINEJOIN_BEVEL :
+ {
+ Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinBevel);
+ break;
+ }
+ case basegfx::B2DLINEJOIN_MIDDLE :
+ case basegfx::B2DLINEJOIN_MITER :
+ {
+ const Gdiplus::REAL aMiterLimit(15.0);
+ Gdiplus::DllExports::GdipSetPenMiterLimit(pTestPen, aMiterLimit);
+ Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinMiter);
+ break;
+ }
+ case basegfx::B2DLINEJOIN_ROUND :
+ {
+ Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinRound);
+ break;
+ }
+ }
+
+ switch(eLineCap)
+ {
+ default: /*com::sun::star::drawing::LineCap_BUTT*/
+ {
+ // nothing to do
+ break;
+ }
+ case com::sun::star::drawing::LineCap_ROUND:
+ {
+ Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapRound);
+ Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapRound);
+ break;
+ }
+ case com::sun::star::drawing::LineCap_SQUARE:
+ {
+ Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapSquare);
+ Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapSquare);
+ break;
+ }
+ }
+
+ if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
+ {
+ impAddB2DPolygonToGDIPlusGraphicsPathInteger(pPath, rPolygon, bNoLineJoin);
+ }
+ else
+ {
+ impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolygon, bNoLineJoin);
+ }
+
+ if(rPolygon.isClosed() && !bNoLineJoin)
+ {
+ // #i101491# needed to create the correct line joins
+ Gdiplus::DllExports::GdipClosePathFigure(pPath);
+ }
+
+ if(mrParent.getAntiAliasB2DDraw())
+ {
+ Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
+ }
+ else
+ {
+ Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
+ }
+
+ Gdiplus::DllExports::GdipDrawPath(pGraphics, pTestPen, pPath);
+
+ Gdiplus::DllExports::GdipDeletePath(pPath);
+ Gdiplus::DllExports::GdipDeletePen(pTestPen);
+ Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
+ }
+
+ return true;
+}
+
+void paintToGdiPlus(
+ Gdiplus::Graphics& rGraphics,
+ const SalTwoRect& rTR,
+ Gdiplus::Bitmap& rBitmap)
+{
+ // only parts of source are used
+ Gdiplus::PointF aDestPoints[3];
+ Gdiplus::ImageAttributes aAttributes;
+
+ // define target region as paralellogram
+ aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX);
+ aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY);
+ aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth);
+ aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY);
+ aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX);
+ aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight);
+
+ aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
+
+ rGraphics.DrawImage(
+ &rBitmap,
+ aDestPoints,
+ 3,
+ Gdiplus::REAL(rTR.mnSrcX),
+ Gdiplus::REAL(rTR.mnSrcY),
+ Gdiplus::REAL(rTR.mnSrcWidth),
+ Gdiplus::REAL(rTR.mnSrcHeight),
+ Gdiplus::UnitPixel,
+ &aAttributes,
+ 0,
+ 0);
+}
+
+void setInterpolationMode(
+ Gdiplus::Graphics& rGraphics,
+ const long& rSrcWidth,
+ const long& rDestWidth,
+ const long& rSrcHeight,
+ const long& rDestHeight)
+{
+ const bool bSameWidth(rSrcWidth == rDestWidth);
+ const bool bSameHeight(rSrcHeight == rDestHeight);
+
+ if(bSameWidth && bSameHeight)
+ {
+#ifdef __MINGW32__
+ //Gdiplus::InterpolationModeInvalid is missing on mingw
+ rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
+#else
+ rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid);
+#endif
+ }
+ else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight)
+ {
+ rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
+ }
+ else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight)
+ {
+ rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
+ }
+ else
+ {
+ rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
+ }
+}
+
+bool WinSalGraphicsImpl::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap)
+{
+ if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
+ {
+ const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
+ GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
+
+ if(aARGB.get())
+ {
+ Gdiplus::Graphics aGraphics(mrParent.getHDC());
+
+ setInterpolationMode(
+ aGraphics,
+ rTR.mnSrcWidth,
+ rTR.mnDestWidth,
+ rTR.mnSrcHeight,
+ rTR.mnDestHeight);
+
+ paintToGdiPlus(
+ aGraphics,
+ rTR,
+ *aARGB.get());
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool WinSalGraphicsImpl::drawAlphaBitmap(
+ const SalTwoRect& rTR,
+ const SalBitmap& rSrcBitmap,
+ const SalBitmap& rAlphaBmp)
+{
+ if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
+ {
+ const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
+ const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp);
+ GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha));
+
+ if(aARGB.get())
+ {
+ Gdiplus::Graphics aGraphics(mrParent.getHDC());
+
+ setInterpolationMode(
+ aGraphics,
+ rTR.mnSrcWidth,
+ rTR.mnDestWidth,
+ rTR.mnSrcHeight,
+ rTR.mnDestHeight);
+
+ paintToGdiPlus(
+ aGraphics,
+ rTR,
+ *aARGB.get());
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool WinSalGraphicsImpl::drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap)
+{
+ const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap);
+ const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap);
+ GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
+
+ if(aARGB.get())
+ {
+ const long nSrcWidth(aARGB->GetWidth());
+ const long nSrcHeight(aARGB->GetHeight());
+
+ if(nSrcWidth && nSrcHeight)
+ {
+ const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength()));
+ const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength()));
+
+ if(nDestWidth && nDestHeight)
+ {
+ Gdiplus::Graphics aGraphics(mrParent.getHDC());
+ Gdiplus::PointF aDestPoints[3];
+ Gdiplus::ImageAttributes aAttributes;
+
+ setInterpolationMode(
+ aGraphics,
+ nSrcWidth,
+ nDestWidth,
+ nSrcHeight,
+ nDestHeight);
+
+ // this mode is only capable of drawing the whole bitmap to a paralellogram
+ aDestPoints[0].X = Gdiplus::REAL(rNull.getX());
+ aDestPoints[0].Y = Gdiplus::REAL(rNull.getY());
+ aDestPoints[1].X = Gdiplus::REAL(rX.getX());
+ aDestPoints[1].Y = Gdiplus::REAL(rX.getY());
+ aDestPoints[2].X = Gdiplus::REAL(rY.getX());
+ aDestPoints[2].Y = Gdiplus::REAL(rY.getY());
+
+ aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
+
+ aGraphics.DrawImage(
+ aARGB.get(),
+ aDestPoints,
+ 3,
+ Gdiplus::REAL(0.0),
+ Gdiplus::REAL(0.0),
+ Gdiplus::REAL(nSrcWidth),
+ Gdiplus::REAL(nSrcHeight),
+ Gdiplus::UnitPixel,
+ &aAttributes,
+ 0,
+ 0);
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool WinSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
+ const Gradient& /*rGradient*/)
+{
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx
new file mode 100644
index 000000000000..2a0780f21738
--- /dev/null
+++ b/vcl/win/source/gdi/gdiimpl.hxx
@@ -0,0 +1,218 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "salgdiimpl.hxx"
+
+#include <vcl/gradient.hxx>
+
+#include "svsys.h"
+
+class WinSalGraphics;
+
+class WinSalGraphicsImpl : public SalGraphicsImpl
+{
+private:
+
+ WinSalGraphics& mrParent;
+ bool mbXORMode : 1; // _every_ output with RasterOp XOR
+ bool mbPen : 1; // is Pen (FALSE == NULL_PEN)
+ HPEN mhPen; // Pen
+ bool mbStockPen : 1; // is Pen a stockpen
+ bool mbBrush : 1; // is Brush (FALSE == NULL_BRUSH)
+ bool mbStockBrush : 1; // is Brush a stcokbrush
+ HBRUSH mhBrush; // Brush
+ COLORREF mnPenColor; // PenColor
+ COLORREF mnBrushColor; // BrushColor
+
+ // remember RGB values for SetLineColor/SetFillColor
+ SalColor maLineColor;
+ SalColor maFillColor;
+
+ bool tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap);
+
+public:
+
+ WinSalGraphicsImpl(WinSalGraphics& rParent);
+
+ virtual ~WinSalGraphicsImpl();
+
+ virtual void freeResources() SAL_OVERRIDE;
+
+ virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
+ //
+ // get the depth of the device
+ virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+ // get the width of the device
+ virtual long GetGraphicsWidth() const SAL_OVERRIDE;
+
+ // set the clip region to empty
+ virtual void ResetClipRegion() SAL_OVERRIDE;
+
+ // set the line color to transparent (= don't draw lines)
+
+ virtual void SetLineColor() SAL_OVERRIDE;
+
+ // set the line color to a specific color
+ virtual void SetLineColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // set the fill color to transparent (= don't fill)
+ virtual void SetFillColor() SAL_OVERRIDE;
+
+ // set the fill color to a specific color, shapes will be
+ // filled accordingly
+ virtual void SetFillColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+ // enable/disable XOR drawing
+ virtual void SetXORMode( bool bSet, bool bInvertOnly ) SAL_OVERRIDE;
+
+ // set line color for raster operations
+ virtual void SetROPLineColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // set fill color for raster operations
+ virtual void SetROPFillColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+ // draw --> LineColor and FillColor and RasterOp and ClipRegion
+ virtual void drawPixel( long nX, long nY ) SAL_OVERRIDE;
+ virtual void drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
+
+ virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
+
+ virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+ virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) SAL_OVERRIDE;
+ virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) SAL_OVERRIDE;
+
+ virtual bool drawPolyLine(
+ const ::basegfx::B2DPolygon&,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin,
+ com::sun::star::drawing::LineCap) SAL_OVERRIDE;
+
+ virtual bool drawPolyLineBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolygonBezier(
+ sal_uInt32 nPoints,
+ const SalPoint* pPtAry,
+ const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+ virtual bool drawPolyPolygonBezier(
+ sal_uInt32 nPoly,
+ const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry,
+ const sal_uInt8* const* pFlgAry ) SAL_OVERRIDE;
+
+ // CopyArea --> No RasterOp, but ClipRegion
+ virtual void copyArea(
+ long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ sal_uInt16 nFlags ) SAL_OVERRIDE;
+
+ // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+ // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+ virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
+
+ virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor ) SAL_OVERRIDE;
+
+ virtual void drawBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rMaskBitmap ) SAL_OVERRIDE;
+
+ virtual void drawMask(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor ) SAL_OVERRIDE;
+
+ virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+ virtual SalColor getPixel( long nX, long nY ) SAL_OVERRIDE;
+
+ // invert --> ClipRegion (only Windows or VirDevs)
+ virtual void invert(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ SalInvert nFlags) SAL_OVERRIDE;
+
+ virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) SAL_OVERRIDE;
+
+ virtual bool drawEPS(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ void* pPtr,
+ sal_uLong nSize ) SAL_OVERRIDE;
+
+ /** Render bitmap with alpha channel
+
+ @param rSourceBitmap
+ Source bitmap to blit
+
+ @param rAlphaBitmap
+ Alpha channel to use for blitting
+
+ @return true, if the operation succeeded, and false
+ otherwise. In this case, clients should try to emulate alpha
+ compositing themselves
+ */
+ virtual bool drawAlphaBitmap(
+ const SalTwoRect&,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
+ /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+ virtual bool drawTransformedBitmap(
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY,
+ const SalBitmap& rSourceBitmap,
+ const SalBitmap* pAlphaBitmap) SAL_OVERRIDE;
+
+ /** Render solid rectangle with given transparency
+
+ @param nTransparency
+ Transparency value (0-255) to use. 0 blits and opaque, 255 a
+ fully transparent rectangle
+ */
+ virtual bool drawAlphaRect(
+ long nX, long nY,
+ long nWidth, long nHeight,
+ sal_uInt8 nTransparency ) SAL_OVERRIDE;
+
+
+ virtual bool drawGradient(const tools::PolyPolygon& rPolygon,
+ const Gradient& rGradient) SAL_OVERRIDE;
+
+ virtual bool swapBuffers() SAL_OVERRIDE { return false; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx
index 912144401069..0f8906c84bc0 100644
--- a/vcl/win/source/gdi/salbmp.cxx
+++ b/vcl/win/source/gdi/salbmp.cxx
@@ -1076,4 +1076,9 @@ bool WinSalBitmap::GetSystemData( BitmapSystemData& rData )
return bRet;
}
+bool WinSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, sal_uInt32 /*nScaleFlag*/ )
+{
+ return false;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 80ce1fdd317c..4e3b76f93455 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -32,8 +32,13 @@
#include <win/salframe.h>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
-// comment out to prevent use of beziers on GDI functions
-#define USE_GDI_BEZIERS
+#include "salgdiimpl.hxx"
+#include "gdiimpl.hxx"
+#include "opengl/win/gdiimpl.hxx"
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include <officecfg/Office/Common.hxx>
#define DITHER_PAL_DELTA 51
#define DITHER_PAL_STEPS 6
@@ -106,9 +111,6 @@ static BYTE aOrdDither16Bit[8][8] =
// complex is set
#define GSL_PEN_WIDTH 1
-#define SAL_POLYPOLYCOUNT_STACKBUF 8
-#define SAL_POLYPOLYPOINTS_STACKBUF 64
-
void ImplInitSalGDI()
{
SalData* pSalData = GetSalData();
@@ -365,6 +367,23 @@ void ImplFreeSalGDI()
pSalData->mbResourcesAlreadyFreed = true;
}
+int ImplIsSysColorEntry( SalColor nSalColor )
+{
+ SysColorEntry* pEntry = pFirstSysColor;
+ const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ while ( pEntry )
+ {
+ if ( pEntry->nRGB == nTestRGB )
+ return TRUE;
+ pEntry = pEntry->pNext;
+ }
+
+ return FALSE;
+}
+
static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
{
// dither color?
@@ -391,23 +410,6 @@ static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
return FALSE;
}
-int ImplIsSysColorEntry( SalColor nSalColor )
-{
- SysColorEntry* pEntry = pFirstSysColor;
- const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
-
- while ( pEntry )
- {
- if ( pEntry->nRGB == nTestRGB )
- return TRUE;
- pEntry = pEntry->pNext;
- }
-
- return FALSE;
-}
-
static void ImplInsertSysColorEntry( int nSysIndex )
{
const DWORD nRGB = GetSysColor( nSysIndex );
@@ -466,44 +468,42 @@ void ImplUpdateSysColorEntries()
ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
}
-static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
-{
- SalColor nSalColor;
- if ( nROPColor == SAL_ROP_0 )
- nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
- else
- nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
- return nSalColor;
-}
-
-void ImplSalInitGraphics( WinSalGraphics* pData )
+void WinSalGraphics::InitGraphics()
{
// calculate the minimal line width for the printer
- if ( pData->mbPrinter )
+ if ( isPrinter() )
{
- int nDPIX = GetDeviceCaps( pData->getHDC(), LOGPIXELSX );
+ int nDPIX = GetDeviceCaps( getHDC(), LOGPIXELSX );
if ( nDPIX <= 300 )
- pData->mnPenWidth = 0;
+ mnPenWidth = 0;
else
- pData->mnPenWidth = nDPIX/300;
+ mnPenWidth = nDPIX/300;
}
- ::SetTextAlign( pData->getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
- ::SetBkMode( pData->getHDC(), WIN32_TRANSPARENT );
- ::SetROP2( pData->getHDC(), R2_COPYPEN );
+ ::SetTextAlign( getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
+ ::SetBkMode( getHDC(), WIN32_TRANSPARENT );
+ ::SetROP2( getHDC(), R2_COPYPEN );
+
+ OpenGLSalGraphicsImpl* pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
+ if (pImpl)
+ {
+ if (mbVirDev)
+ pImpl->GetOpenGLContext().requestVirtualDevice();
+ pImpl->GetOpenGLContext().init(mhLocalDC, mhWnd);
+ }
}
-void ImplSalDeInitGraphics( WinSalGraphics* pData )
+void WinSalGraphics::DeInitGraphics()
{
// clear clip region
- SelectClipRgn( pData->getHDC(), 0 );
+ SelectClipRgn( getHDC(), 0 );
// select default objects
- if ( pData->mhDefPen )
- SelectPen( pData->getHDC(), pData->mhDefPen );
- if ( pData->mhDefBrush )
- SelectBrush( pData->getHDC(), pData->mhDefBrush );
- if ( pData->mhDefFont )
- SelectFont( pData->getHDC(), pData->mhDefFont );
+ if ( mhDefPen )
+ SelectPen( getHDC(), mhDefPen );
+ if ( mhDefBrush )
+ SelectBrush( getHDC(), mhDefBrush );
+ if ( mhDefFont )
+ SelectFont( getHDC(), mhDefFont );
}
HDC ImplGetCachedDC( sal_uLong nID, HBITMAP hBmp )
@@ -566,107 +566,36 @@ void ImplClearHDCCache( SalData* pData )
}
}
-// #100127# Fill point and flag memory from array of points which
-// might also contain bezier control points for the PolyDraw() GDI method
-// Make sure pWinPointAry and pWinFlagAry are big enough
-void ImplPreparePolyDraw( bool bCloseFigures,
- sal_uLong nPoly,
- const sal_uInt32* pPoints,
- const SalPoint* const* pPtAry,
- const BYTE* const* pFlgAry,
- POINT* pWinPointAry,
- BYTE* pWinFlagAry )
+WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd):
+ mhLocalDC(0),
+ mbPrinter(eType == WinSalGraphics::PRINTER),
+ mbVirDev(eType == WinSalGraphics::VIRTUAL_DEVICE),
+ mbWindow(eType == WinSalGraphics::WINDOW),
+ mhWnd(hWnd),
+ mbScreen(bScreen),
+ mfCurrentFontScale(1.0),
+ mhRegion(0),
+ mhDefPen(0),
+ mhDefBrush(0),
+ mhDefFont(0),
+ mhDefPal(0),
+ mpStdClipRgnData(NULL),
+ mpLogFont(NULL),
+ mpFontCharSets(NULL),
+ mpFontAttrCache(NULL),
+ mnFontCharSetCount(0),
+ mpFontKernPairs(NULL),
+ mnFontKernPairCount(0),
+ mbFontKernInit(false),
+ mnPenWidth(GSL_PEN_WIDTH)
{
- sal_uLong nCurrPoly;
- for( nCurrPoly=0; nCurrPoly<nPoly; ++nCurrPoly )
- {
- const POINT* pCurrPoint = reinterpret_cast<const POINT*>( *pPtAry++ );
- const BYTE* pCurrFlag = *pFlgAry++;
- const sal_uInt32 nCurrPoints = *pPoints++;
- const bool bHaveFlagArray( pCurrFlag );
- sal_uLong nCurrPoint;
-
- if( nCurrPoints )
- {
- // start figure
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_MOVETO;
- ++pCurrFlag;
-
- for( nCurrPoint=1; nCurrPoint<nCurrPoints; )
- {
- // #102067# Check existence of flag array
- if( bHaveFlagArray &&
- ( nCurrPoint + 2 ) < nCurrPoints )
- {
- BYTE P4( pCurrFlag[ 2 ] );
-
- if( ( POLY_CONTROL == pCurrFlag[ 0 ] ) &&
- ( POLY_CONTROL == pCurrFlag[ 1 ] ) &&
- ( POLY_NORMAL == P4 || POLY_SMOOTH == P4 || POLY_SYMMTR == P4 ) )
- {
- // control point one
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- // control point two
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- // end point
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_BEZIERTO;
-
- nCurrPoint += 3;
- pCurrFlag += 3;
- continue;
- }
- }
-
- // regular line point
- *pWinPointAry++ = *pCurrPoint++;
- *pWinFlagAry++ = PT_LINETO;
- ++pCurrFlag;
- ++nCurrPoint;
- }
-
- // end figure?
- if( bCloseFigures )
- pWinFlagAry[-1] |= PT_CLOSEFIGURE;
- }
- }
-}
-
-// #100127# draw an array of points which might also contain bezier control points
-void ImplRenderPath( HDC hdc, sal_uLong nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
-{
- if( nPoints )
- {
- sal_uInt16 i;
- // TODO: profile whether the following options are faster:
- // a) look ahead and draw consecutive bezier or line segments by PolyBezierTo/PolyLineTo resp.
- // b) convert our flag array to window's and use PolyDraw
-
- MoveToEx( hdc, pPtAry->mnX, pPtAry->mnY, NULL );
- ++pPtAry; ++pFlgAry;
-
- for( i=1; i<nPoints; ++i, ++pPtAry, ++pFlgAry )
- {
- if( *pFlgAry != POLY_CONTROL )
- {
- LineTo( hdc, pPtAry->mnX, pPtAry->mnY );
- }
- else if( nPoints - i > 2 )
- {
- PolyBezierTo( hdc, reinterpret_cast<const POINT*>(pPtAry), 3 );
- i += 2; pPtAry += 2; pFlgAry += 2;
- }
- }
- }
-}
+ static bool bOpenGLPossible = OpenGLHelper::supportsVCLOpenGL();
+ bool bUseOpenGL = bOpenGLPossible && mbWindow ? officecfg::Office::Common::VCL::UseOpenGL::get() : false;
+ if (bUseOpenGL)
+ mpImpl.reset(new WinOpenGLSalGraphicsImpl(*this));
+ else
+ mpImpl.reset(new WinSalGraphicsImpl(*this));
-WinSalGraphics::WinSalGraphics()
-{
for( int i = 0; i < MAX_FALLBACK; ++i )
{
mhFonts[ i ] = 0;
@@ -674,44 +603,12 @@ WinSalGraphics::WinSalGraphics()
mpWinFontEntry[ i ] = NULL;
mfFontScale[ i ] = 1.0;
}
-
- mfCurrentFontScale = 1.0;
-
- mhLocalDC = 0;
- mhPen = 0;
- mhBrush = 0;
- mhRegion = 0;
- mhDefPen = 0;
- mhDefBrush = 0;
- mhDefFont = 0;
- mhDefPal = 0;
- mpStdClipRgnData = NULL;
- mpLogFont = NULL;
- mpFontCharSets = NULL;
- mpFontAttrCache = NULL;
- mnFontCharSetCount = 0;
- mpFontKernPairs = NULL;
- mnFontKernPairCount = 0;
- mbFontKernInit = FALSE;
- mbXORMode = FALSE;
- mnPenWidth = GSL_PEN_WIDTH;
}
WinSalGraphics::~WinSalGraphics()
{
// free obsolete GDI objects
- ReleaseFonts();
-
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
+ ReleaseFonts();
if ( mhRegion )
{
@@ -720,8 +617,7 @@ WinSalGraphics::~WinSalGraphics()
}
// delete cache data
- if ( mpStdClipRgnData )
- delete [] mpStdClipRgnData;
+ delete [] mpStdClipRgnData;
delete mpLogFont;
@@ -730,6 +626,51 @@ WinSalGraphics::~WinSalGraphics()
delete mpFontKernPairs;
}
+bool WinSalGraphics::isPrinter() const
+{
+ return mbPrinter;
+}
+
+bool WinSalGraphics::isVirtualDevice() const
+{
+ return mbVirDev;
+}
+
+bool WinSalGraphics::isWindow() const
+{
+ return mbWindow;
+}
+
+bool WinSalGraphics::isScreen() const
+{
+ return mbScreen;
+}
+
+HWND WinSalGraphics::gethWnd()
+{
+ return mhWnd;
+}
+
+void WinSalGraphics::setHWND(HWND hWnd)
+{
+ mhWnd = hWnd;
+}
+
+HPALETTE WinSalGraphics::getDefPal() const
+{
+ return mhDefPal;
+}
+
+void WinSalGraphics::setDefPal(HPALETTE hDefPal)
+{
+ mhDefPal = hDefPal;
+}
+
+HRGN WinSalGraphics::getRegion() const
+{
+ return mhRegion;
+}
+
void WinSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
{
rDPIX = GetDeviceCaps( getHDC(), LOGPIXELSX );
@@ -744,839 +685,111 @@ void WinSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
sal_uInt16 WinSalGraphics::GetBitCount() const
{
- return (sal_uInt16)GetDeviceCaps( getHDC(), BITSPIXEL );
+ return mpImpl->GetBitCount();
}
long WinSalGraphics::GetGraphicsWidth() const
{
- if( mhWnd && IsWindow( mhWnd ) )
- {
- WinSalFrame* pFrame = GetWindowPtr( mhWnd );
- if( pFrame )
- {
- if( pFrame->maGeometry.nWidth )
- return pFrame->maGeometry.nWidth;
- else
- {
- // TODO: perhaps not needed, maGeometry should always be up-to-date
- RECT aRect;
- GetClientRect( mhWnd, &aRect );
- return aRect.right;
- }
- }
- }
-
- return 0;
+ return mpImpl->GetGraphicsWidth();
}
void WinSalGraphics::ResetClipRegion()
{
- if ( mhRegion )
- {
- DeleteRegion( mhRegion );
- mhRegion = 0;
- }
-
- SelectClipRgn( getHDC(), 0 );
+ mpImpl->ResetClipRegion();
}
bool WinSalGraphics::setClipRegion( const vcl::Region& i_rClip )
{
- if ( mhRegion )
- {
- DeleteRegion( mhRegion );
- mhRegion = 0;
- }
-
- bool bUsePolygon(i_rClip.HasPolyPolygonOrB2DPolyPolygon());
- static bool bTryToAvoidPolygon(true);
-
- // #i122149# try to avoid usage of tools::PolyPolygon ClipRegions when tools::PolyPolygon is no curve
- // and only contains horizontal/vertical edges. In that case, use the fallback
- // in GetRegionRectangles which will use vcl::Region::GetAsRegionBand() which will do
- // the correct polygon-to-RegionBand transformation.
- // Background is that when using the same Rectangle as rectangle or as Polygon
- // clip region will lead to different results; the polygon-based one will be
- // one pixel less to the right and down (see GDI docu for CreatePolygonRgn). This
- // again is because of the polygon-nature and it's classic handling when filling.
- // This also means that all cases which use a 'true' polygon-based incarnation of
- // a vcl::Region should know what they do - it may lead to repaint errors.
- if(bUsePolygon && bTryToAvoidPolygon)
- {
- const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
-
- if(!aPolyPolygon.areControlPointsUsed())
- {
- if(basegfx::tools::containsOnlyHorizontalAndVerticalEdges(aPolyPolygon))
- {
- bUsePolygon = false;
- }
- }
- }
-
- if(bUsePolygon)
- {
- // #i122149# check the comment above to know that this may lead to potential repaint
- // problems. It may be solved (if needed) by scaling the polygon by one in X
- // and Y. Currently the workaround to only use it if really unavoidable will
- // solve most cases. When someone is really using polygon-based Regions he
- // should know what he is doing.
- // Added code to do that scaling to check if it works, testing it.
- const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
- const sal_uInt32 nCount(aPolyPolygon.count());
-
- if( nCount )
- {
- std::vector< POINT > aPolyPoints;
- aPolyPoints.reserve( 1024 );
- std::vector< INT > aPolyCounts( nCount, 0 );
- basegfx::B2DHomMatrix aExpand;
- static bool bExpandByOneInXandY(true);
-
- if(bExpandByOneInXandY)
- {
- const basegfx::B2DRange aRangeS(aPolyPolygon.getB2DRange());
- const basegfx::B2DRange aRangeT(aRangeS.getMinimum(), aRangeS.getMaximum() + basegfx::B2DTuple(1.0, 1.0));
- aExpand = basegfx::B2DHomMatrix(basegfx::tools::createSourceRangeTargetRangeTransform(aRangeS, aRangeT));
- }
-
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- const basegfx::B2DPolygon aPoly(
- basegfx::tools::adaptiveSubdivideByDistance(
- aPolyPolygon.getB2DPolygon(a),
- 1));
- const sal_uInt32 nPoints(aPoly.count());
- aPolyCounts[a] = nPoints;
-
- for( sal_uInt32 b = 0; b < nPoints; b++ )
- {
- basegfx::B2DPoint aPt(aPoly.getB2DPoint(b));
-
- if(bExpandByOneInXandY)
- {
- aPt = aExpand * aPt;
- }
-
- POINT aPOINT;
- // #i122149# do correct rounding
- aPOINT.x = basegfx::fround(aPt.getX());
- aPOINT.y = basegfx::fround(aPt.getY());
- aPolyPoints.push_back( aPOINT );
- }
- }
-
- mhRegion = CreatePolyPolygonRgn( &aPolyPoints[0], &aPolyCounts[0], nCount, ALTERNATE );
- }
- }
- else
- {
- RectangleVector aRectangles;
- i_rClip.GetRegionRectangles(aRectangles);
-
- sal_uLong nRectBufSize = sizeof(RECT)*aRectangles.size();
- if ( aRectangles.size() < SAL_CLIPRECT_COUNT )
- {
- if ( !mpStdClipRgnData )
- mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
- mpClipRgnData = mpStdClipRgnData;
- }
- else
- mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
- mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
- mpClipRgnData->rdh.iType = RDH_RECTANGLES;
- mpClipRgnData->rdh.nCount = aRectangles.size();
- mpClipRgnData->rdh.nRgnSize = nRectBufSize;
- RECT* pBoundRect = &(mpClipRgnData->rdh.rcBound);
- SetRectEmpty( pBoundRect );
- RECT* pNextClipRect = (RECT*)(&(mpClipRgnData->Buffer));
- bool bFirstClipRect = true;
-
- for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
- {
- const long nW(aRectIter->GetWidth());
- const long nH(aRectIter->GetHeight());
-
- if(nW && nH)
- {
- const long nRight(aRectIter->Left() + nW);
- const long nBottom(aRectIter->Top() + nH);
-
- if(bFirstClipRect)
- {
- pBoundRect->left = aRectIter->Left();
- pBoundRect->top = aRectIter->Top();
- pBoundRect->right = nRight;
- pBoundRect->bottom = nBottom;
- bFirstClipRect = false;
- }
- else
- {
- if(aRectIter->Left() < pBoundRect->left)
- {
- pBoundRect->left = (int)aRectIter->Left();
- }
-
- if(aRectIter->Top() < pBoundRect->top)
- {
- pBoundRect->top = (int)aRectIter->Top();
- }
-
- if(nRight > pBoundRect->right)
- {
- pBoundRect->right = (int)nRight;
- }
-
- if(nBottom > pBoundRect->bottom)
- {
- pBoundRect->bottom = (int)nBottom;
- }
- }
-
- pNextClipRect->left = (int)aRectIter->Left();
- pNextClipRect->top = (int)aRectIter->Top();
- pNextClipRect->right = (int)nRight;
- pNextClipRect->bottom = (int)nBottom;
- pNextClipRect++;
- }
- else
- {
- mpClipRgnData->rdh.nCount--;
- mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
- }
- }
-
- // create clip region from ClipRgnData
- if(0 == mpClipRgnData->rdh.nCount)
- {
- // #i123585# region is empty; this may happen when e.g. a tools::PolyPolygon is given
- // that contains no polygons or only empty ones (no width/height). This is
- // perfectly fine and we are done, except setting it (see end of method)
- }
- else if(1 == mpClipRgnData->rdh.nCount)
- {
- RECT* pRect = &(mpClipRgnData->rdh.rcBound);
- mhRegion = CreateRectRgn( pRect->left, pRect->top,
- pRect->right, pRect->bottom );
- }
- else if(mpClipRgnData->rdh.nCount > 1)
- {
- sal_uLong nSize = mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
- mhRegion = ExtCreateRegion( NULL, nSize, mpClipRgnData );
-
- // if ExtCreateRegion(...) is not supported
- if( !mhRegion )
- {
- RGNDATAHEADER* pHeader = (RGNDATAHEADER*) mpClipRgnData;
-
- if( pHeader->nCount )
- {
- RECT* pRect = (RECT*) mpClipRgnData->Buffer;
- mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
- pRect++;
-
- for( sal_uLong n = 1; n < pHeader->nCount; n++, pRect++ )
- {
- HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
- CombineRgn( mhRegion, mhRegion, hRgn, RGN_OR );
- DeleteRegion( hRgn );
- }
- }
- }
-
- if ( mpClipRgnData != mpStdClipRgnData )
- delete [] mpClipRgnData;
- }
- }
-
- if( mhRegion )
- {
- SelectClipRgn( getHDC(), mhRegion );
-
- // debug code if you weant to check range of the newly applied ClipRegion
- //RECT aBound;
- //const int aRegionType = GetRgnBox(mhRegion, &aBound);
-
- //bool bBla = true;
- }
- else
- {
- // #i123585# See above, this is a valid case, execute it
- SelectClipRgn( getHDC(), 0 );
- }
-
- // #i123585# retval no longer dependent of mhRegion, see TaskId comments above
- return true;
+ return mpImpl->setClipRegion( i_rClip );
}
void WinSalGraphics::SetLineColor()
{
- // create and select new pen
- HPEN hNewPen = GetStockPen( NULL_PEN );
- HPEN hOldPen = SelectPen( getHDC(), hNewPen );
-
- // destroy or save old pen
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- else
- mhDefPen = hOldPen;
-
- // set new data
- mhPen = hNewPen;
- mbPen = FALSE;
- mbStockPen = TRUE;
+ mpImpl->SetLineColor();
}
void WinSalGraphics::SetLineColor( SalColor nSalColor )
{
- maLineColor = nSalColor;
- COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
- HPEN hNewPen = 0;
- bool bStockPen = FALSE;
-
- // search for stock pen (only screen, because printer have problems,
- // when we use stock objects)
- if ( !mbPrinter )
- {
- SalData* pSalData = GetSalData();
- for ( sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++ )
- {
- if ( nPenColor == pSalData->maStockPenColorAry[i] )
- {
- hNewPen = pSalData->mhStockPenAry[i];
- bStockPen = TRUE;
- break;
- }
- }
- }
-
- // create new pen
- if ( !hNewPen )
- {
- if ( !mbPrinter )
- {
- if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
- nPenColor = PALRGB_TO_RGB( nPenColor );
- }
-
- hNewPen = CreatePen( PS_SOLID, mnPenWidth, nPenColor );
- bStockPen = FALSE;
- }
-
- // select new pen
- HPEN hOldPen = SelectPen( getHDC(), hNewPen );
-
- // destroy or save old pen
- if ( mhPen )
- {
- if ( !mbStockPen )
- DeletePen( mhPen );
- }
- else
- mhDefPen = hOldPen;
-
- // set new data
- mnPenColor = nPenColor;
- mhPen = hNewPen;
- mbPen = TRUE;
- mbStockPen = bStockPen;
+ mpImpl->SetLineColor( nSalColor );
}
void WinSalGraphics::SetFillColor()
{
- // create and select new brush
- HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush );
-
- // destroy or save old brush
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
- else
- mhDefBrush = hOldBrush;
-
- // set new data
- mhBrush = hNewBrush;
- mbBrush = FALSE;
- mbStockBrush = TRUE;
+ mpImpl->SetFillColor();
}
void WinSalGraphics::SetFillColor( SalColor nSalColor )
{
- maFillColor = nSalColor;
- SalData* pSalData = GetSalData();
- BYTE nRed = SALCOLOR_RED( nSalColor );
- BYTE nGreen = SALCOLOR_GREEN( nSalColor );
- BYTE nBlue = SALCOLOR_BLUE( nSalColor );
- COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
- HBRUSH hNewBrush = 0;
- bool bStockBrush = FALSE;
-
- // search for stock brush (only screen, because printer have problems,
- // when we use stock objects)
- if ( !mbPrinter )
- {
- for ( sal_uInt16 i = 0; i < pSalData->mnStockBrushCount; i++ )
- {
- if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
- {
- hNewBrush = pSalData->mhStockBrushAry[i];
- bStockBrush = TRUE;
- break;
- }
- }
- }
-
- // create new brush
- if ( !hNewBrush )
- {
- if ( mbPrinter || !pSalData->mhDitherDIB )
- hNewBrush = CreateSolidBrush( nBrushColor );
- else
- {
- if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
- {
- BYTE* pTmp = pSalData->mpDitherDIBData;
- long* pDitherDiff = pSalData->mpDitherDiff;
- BYTE* pDitherLow = pSalData->mpDitherLow;
- BYTE* pDitherHigh = pSalData->mpDitherHigh;
-
- for( long nY = 0L; nY < 8L; nY++ )
- {
- for( long nX = 0L; nX < 8L; nX++ )
- {
- const long nThres = aOrdDither16Bit[ nY ][ nX ];
- *pTmp++ = DMAP( nBlue, nThres );
- *pTmp++ = DMAP( nGreen, nThres );
- *pTmp++ = DMAP( nRed, nThres );
- }
- }
-
- hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
- }
- else if ( ImplIsSysColorEntry( nSalColor ) )
- {
- nBrushColor = PALRGB_TO_RGB( nBrushColor );
- hNewBrush = CreateSolidBrush( nBrushColor );
- }
- else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
- hNewBrush = CreateSolidBrush( nBrushColor );
- else
- {
- BYTE* pTmp = pSalData->mpDitherDIBData;
- long* pDitherDiff = pSalData->mpDitherDiff;
- BYTE* pDitherLow = pSalData->mpDitherLow;
- BYTE* pDitherHigh = pSalData->mpDitherHigh;
-
- for ( long nY = 0L; nY < 8L; nY++ )
- {
- for ( long nX = 0L; nX < 8L; nX++ )
- {
- const long nThres = aOrdDither8Bit[ nY ][ nX ];
- *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
- pTmp++;
- }
- }
-
- hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
- }
- }
-
- bStockBrush = FALSE;
- }
-
- // select new brush
- HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush );
-
- // destroy or save old brush
- if ( mhBrush )
- {
- if ( !mbStockBrush )
- DeleteBrush( mhBrush );
- }
- else
- mhDefBrush = hOldBrush;
-
- // set new data
- mnBrushColor = nBrushColor;
- mhBrush = hNewBrush;
- mbBrush = TRUE;
- mbStockBrush = bStockBrush;
+ mpImpl->SetFillColor( nSalColor );
}
-void WinSalGraphics::SetXORMode( bool bSet, bool )
+void WinSalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
{
- mbXORMode = bSet;
- ::SetROP2( getHDC(), bSet ? R2_XORPEN : R2_COPYPEN );
+ mpImpl->SetXORMode( bSet, bInvertOnly );
}
void WinSalGraphics::SetROPLineColor( SalROPColor nROPColor )
{
- SetLineColor( ImplGetROPSalColor( nROPColor ) );
+ mpImpl->SetROPLineColor( nROPColor );
}
void WinSalGraphics::SetROPFillColor( SalROPColor nROPColor )
{
- SetFillColor( ImplGetROPSalColor( nROPColor ) );
+ mpImpl->SetROPFillColor( nROPColor );
}
void WinSalGraphics::drawPixel( long nX, long nY )
{
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)nX, (int)nY, mnPenColor );
+ mpImpl->drawPixel( nX, nY );
}
void WinSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
{
- COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
- SALCOLOR_GREEN( nSalColor ),
- SALCOLOR_BLUE( nSalColor ) );
-
- if ( !mbPrinter &&
- GetSalData()->mhDitherPal &&
- ImplIsSysColorEntry( nSalColor ) )
- nCol = PALRGB_TO_RGB( nCol );
-
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( nCol );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- ::SetPixel( getHDC(), (int)nX, (int)nY, nCol );
+ mpImpl->drawPixel( nX, nY, nSalColor );
}
void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
- MoveToEx( getHDC(), (int)nX1, (int)nY1, NULL );
-
- // we must paint the endpoint
- int bPaintEnd = TRUE;
- if ( nX1 == nX2 )
- {
- bPaintEnd = FALSE;
- if ( nY1 <= nY2 )
- nY2++;
- else
- nY2--;
- }
- if ( nY1 == nY2 )
- {
- bPaintEnd = FALSE;
- if ( nX1 <= nX2 )
- nX2++;
- else
- nX2--;
- }
-
- LineTo( getHDC(), (int)nX2, (int)nY2 );
-
- if ( bPaintEnd && !mbPrinter )
- {
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)nX2, (int)nY2, mnPenColor );
- }
+ mpImpl->drawLine( nX1, nY1, nX2, nY2 );
}
void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
{
- if ( !mbPen )
- {
- if ( !mbPrinter )
- {
- PatBlt( getHDC(), (int)nX, (int)nY, (int)nWidth, (int)nHeight,
- mbXORMode ? PATINVERT : PATCOPY );
- }
- else
- {
- RECT aWinRect;
- aWinRect.left = nX;
- aWinRect.top = nY;
- aWinRect.right = nX+nWidth;
- aWinRect.bottom = nY+nHeight;
- ::FillRect( getHDC(), &aWinRect, mhBrush );
- }
- }
- else
- WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+ mpImpl->drawRect( nX, nY, nWidth, nHeight );
}
void WinSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" );
-
- POINT* pWinPtAry = (POINT*)pPtAry;
-
- // we assume there are at least 2 points (Polyline requres at least 2 point, see MSDN)
- // we must paint the endpoint for last line
- BOOL bPaintEnd = TRUE;
- if ( pWinPtAry[nPoints-2].x == pWinPtAry[nPoints-1].x )
- {
- bPaintEnd = FALSE;
- if ( pWinPtAry[nPoints-2].y <= pWinPtAry[nPoints-1].y )
- pWinPtAry[nPoints-1].y++;
- else
- pWinPtAry[nPoints-1].y--;
- }
- if ( pWinPtAry[nPoints-2].y == pWinPtAry[nPoints-1].y )
- {
- bPaintEnd = FALSE;
- if ( pWinPtAry[nPoints-2].x <= pWinPtAry[nPoints-1].x )
- pWinPtAry[nPoints-1].x++;
- else
- pWinPtAry[nPoints-1].x--;
- }
-
- // for Windows 95 and its maximum number of points
- if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
-
- if ( bPaintEnd && !mbPrinter )
- {
- if ( mbXORMode )
- {
- HBRUSH hBrush = CreateSolidBrush( mnPenColor );
- HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush );
- PatBlt( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), (int)1, (int)1, PATINVERT );
- SelectBrush( getHDC(), hOldBrush );
- DeleteBrush( hBrush );
- }
- else
- SetPixel( getHDC(), (int)(pWinPtAry[nPoints-1].x), (int)(pWinPtAry[nPoints-1].y), mnPenColor );
- }
+ mpImpl->drawPolyLine( nPoints, pPtAry );
}
void WinSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolygon(): POINT != SalPoint" );
-
- POINT* pWinPtAry = (POINT*)pPtAry;
- // for Windows 95 and its maximum number of points
- if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
+ mpImpl->drawPolygon( nPoints, pPtAry );
}
void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints,
PCONSTSALPOINT* pPtAry )
{
- UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
- UINT* pWinPointAry;
- UINT nPolyPolyPoints = 0;
- UINT nPoints;
- UINT i;
-
- if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
- pWinPointAry = aWinPointAry;
- else
- pWinPointAry = new UINT[nPoly];
-
- for ( i = 0; i < (UINT)nPoly; i++ )
- {
- nPoints = (UINT)pPoints[i]+1;
- pWinPointAry[i] = nPoints;
- nPolyPolyPoints += nPoints;
- }
-
- POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
- POINT* pWinPointAryAry;
- if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
- pWinPointAryAry = aWinPointAryAry;
- else
- pWinPointAryAry = new POINT[nPolyPolyPoints];
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
- const SalPoint* pPolyAry;
- UINT n = 0;
- for ( i = 0; i < (UINT)nPoly; i++ )
- {
- nPoints = pWinPointAry[i];
- pPolyAry = pPtAry[i];
- memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
- pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
- n += nPoints;
- }
-
- if ( !WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
- (nPolyPolyPoints > MAX_64KSALPOINTS) )
- {
- nPolyPolyPoints = 0;
- nPoly = 0;
- do
- {
- nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
- nPoly++;
- }
- while ( nPolyPolyPoints < MAX_64KSALPOINTS );
- nPoly--;
- if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
- pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
- if ( nPoly == 1 )
- WIN_Polygon( getHDC(), pWinPointAryAry, *pWinPointAry );
- else
- WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, nPoly );
- }
-
- if ( pWinPointAry != aWinPointAry )
- delete [] pWinPointAry;
- if ( pWinPointAryAry != aWinPointAryAry )
- delete [] pWinPointAryAry;
+ mpImpl->drawPolyPolygon( nPoly, pPoints, pPtAry );
}
-#define SAL_POLY_STACKBUF 32
-
bool WinSalGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyLineBezier(): POINT != SalPoint" );
-
- ImplRenderPath( getHDC(), nPoints, pPtAry, pFlgAry );
-
- return true;
-#else
- return false;
-#endif
+ return mpImpl->drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
}
bool WinSalGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolygonBezier(): POINT != SalPoint" );
-
- POINT aStackAry1[SAL_POLY_STACKBUF];
- BYTE aStackAry2[SAL_POLY_STACKBUF];
- POINT* pWinPointAry;
- BYTE* pWinFlagAry;
- if( nPoints > SAL_POLY_STACKBUF )
- {
- pWinPointAry = new POINT[ nPoints ];
- pWinFlagAry = new BYTE[ nPoints ];
- }
- else
- {
- pWinPointAry = aStackAry1;
- pWinFlagAry = aStackAry2;
- }
-
- sal_uInt32 nPoints_i32(nPoints);
- ImplPreparePolyDraw(true, 1, &nPoints_i32, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry);
-
- bool bRet( false );
-
- if( BeginPath( getHDC() ) )
- {
- PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nPoints);
-
- if( EndPath( getHDC() ) )
- {
- if( StrokeAndFillPath( getHDC() ) )
- bRet = true;
- }
- }
-
- if( pWinPointAry != aStackAry1 )
- {
- delete [] pWinPointAry;
- delete [] pWinFlagAry;
- }
-
- return bRet;
-#else
- return false;
-#endif
+ return mpImpl->drawPolygonBezier( nPoints, pPtAry, pFlgAry );
}
bool WinSalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints,
const SalPoint* const* pPtAry, const BYTE* const* pFlgAry )
{
-#ifdef USE_GDI_BEZIERS
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyPolygonBezier(): POINT != SalPoint" );
-
- sal_uLong nCurrPoly, nTotalPoints;
- const sal_uInt32* pCurrPoints = pPoints;
- for( nCurrPoly=0, nTotalPoints=0; nCurrPoly<nPoly; ++nCurrPoly )
- nTotalPoints += *pCurrPoints++;
-
- POINT aStackAry1[SAL_POLY_STACKBUF];
- BYTE aStackAry2[SAL_POLY_STACKBUF];
- POINT* pWinPointAry;
- BYTE* pWinFlagAry;
- if( nTotalPoints > SAL_POLY_STACKBUF )
- {
- pWinPointAry = new POINT[ nTotalPoints ];
- pWinFlagAry = new BYTE[ nTotalPoints ];
- }
- else
- {
- pWinPointAry = aStackAry1;
- pWinFlagAry = aStackAry2;
- }
-
- ImplPreparePolyDraw(true, nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry);
-
- bool bRet( false );
-
- if( BeginPath( getHDC() ) )
- {
- PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nTotalPoints);
-
- if( EndPath( getHDC() ) )
- {
- if( StrokeAndFillPath( getHDC() ) )
- bRet = true;
- }
- }
-
- if( pWinPointAry != aStackAry1 )
- {
- delete [] pWinPointAry;
- delete [] pWinFlagAry;
- }
-
- return bRet;
-#else
- return false;
-#endif
+ return mpImpl->drawPolyPolygonBezier( nPoly, pPoints, pPtAry, pFlgAry );
}
-#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
-
static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, sal_uLong nComp, sal_uLong nSize )
{
while ( nComp-- >= nSize )
@@ -1656,9 +869,11 @@ static bool ImplGetBoundingBox( double* nNumb, BYTE* pSource, sal_uLong nSize )
return bRetValue;
}
+#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
+
bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uLong nSize )
{
- bool bRetValue = FALSE;
+ bool bRetValue = false;
if ( mbPrinter )
{
@@ -1814,4 +1029,9 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const
return aRes;
}
+bool WinSalGraphics::SwapBuffers()
+{
+ return mpImpl->swapBuffers();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx
index 16f262fa41c6..f00945164f3e 100644
--- a/vcl/win/source/gdi/salgdi2.cxx
+++ b/vcl/win/source/gdi/salgdi2.cxx
@@ -33,6 +33,7 @@
#include "vcl/salbtype.hxx"
#include "vcl/bmpacc.hxx"
#include "outdata.hxx"
+#include "salgdiimpl.hxx"
bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const
{
@@ -56,82 +57,7 @@ bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const
void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
{
- HDC hSrcDC;
- DWORD nRop;
-
- if ( pSrcGraphics )
- hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC();
- else
- hSrcDC = getHDC();
-
- if ( mbXORMode )
- nRop = SRCINVERT;
- else
- nRop = SRCCOPY;
-
- if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
- (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
- {
- BitBlt( getHDC(),
- (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
- (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
- hSrcDC,
- (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
- nRop );
- }
- else
- {
- int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS );
- StretchBlt( getHDC(),
- (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
- (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
- hSrcDC,
- (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
- (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
- nRop );
- SetStretchBltMode( getHDC(), nOldStretchMode );
- }
-}
-
-void ImplCalcOutSideRgn( const RECT& rSrcRect,
- int nLeft, int nTop, int nRight, int nBottom,
- HRGN& rhInvalidateRgn )
-{
- HRGN hTempRgn;
-
- // calculate area outside the visible region
- if ( rSrcRect.left < nLeft )
- {
- if ( !rhInvalidateRgn )
- rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
- hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 );
- CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
- }
- if ( rSrcRect.top < nTop )
- {
- if ( !rhInvalidateRgn )
- rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
- hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop );
- CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
- }
- if ( rSrcRect.right > nRight )
- {
- if ( !rhInvalidateRgn )
- rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
- hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 );
- CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
- }
- if ( rSrcRect.bottom > nBottom )
- {
- if ( !rhInvalidateRgn )
- rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
- hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 );
- CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
- }
+ mpImpl->copyBits( rPosAry, pSrcGraphics );
}
void WinSalGraphics::copyArea( long nDestX, long nDestY,
@@ -139,688 +65,60 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY,
long nSrcWidth, long nSrcHeight,
sal_uInt16 nFlags )
{
- bool bRestoreClipRgn = false;
- HRGN hOldClipRgn = 0;
- int nOldClipRgnType = ERROR;
- HRGN hInvalidateRgn = 0;
-
- // do we have to invalidate also the overlapping regions?
- if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && mbWindow )
- {
- // compute and invalidate those parts that were either off-screen or covered by other windows
- // while performing the above BitBlt
- // those regions then have to be invalidated as they contain useless/wrong data
- RECT aSrcRect;
- RECT aClipRect;
- RECT aTempRect;
- RECT aTempRect2;
- HRGN hTempRgn;
- HWND hWnd;
-
- // restrict srcRect to this window (calc intersection)
- aSrcRect.left = (int)nSrcX;
- aSrcRect.top = (int)nSrcY;
- aSrcRect.right = aSrcRect.left+(int)nSrcWidth;
- aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight;
- GetClientRect( mhWnd, &aClipRect );
- if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) )
- {
- // transform srcRect to screen coordinates
- POINT aPt;
- aPt.x = 0;
- aPt.y = 0;
- ClientToScreen( mhWnd, &aPt );
- aSrcRect.left += aPt.x;
- aSrcRect.top += aPt.y;
- aSrcRect.right += aPt.x;
- aSrcRect.bottom += aPt.y;
- hInvalidateRgn = 0;
-
- // compute the parts that are off screen (ie invisible)
- RECT theScreen;
- ImplSalGetWorkArea( NULL, &theScreen, NULL ); // find the screen area taking multiple monitors into account
- ImplCalcOutSideRgn( aSrcRect, theScreen.left, theScreen.top, theScreen.right, theScreen.bottom, hInvalidateRgn );
-
- // calculate regions that are covered by other windows
- HRGN hTempRgn2 = 0;
- HWND hWndTopWindow = mhWnd;
- // Find the TopLevel Window, because only Windows which are in
- // in the foreground of our TopLevel window must be considered
- if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD )
- {
- RECT aTempRect3 = aSrcRect;
- do
- {
- hWndTopWindow = ::GetParent( hWndTopWindow );
-
- // Test if the Parent clips our window
- GetClientRect( hWndTopWindow, &aTempRect );
- POINT aPt2;
- aPt2.x = 0;
- aPt2.y = 0;
- ClientToScreen( hWndTopWindow, &aPt2 );
- aTempRect.left += aPt2.x;
- aTempRect.top += aPt2.y;
- aTempRect.right += aPt2.x;
- aTempRect.bottom += aPt2.y;
- IntersectRect( &aTempRect3, &aTempRect3, &aTempRect );
- }
- while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD );
-
- // If one or more Parents clip our window, than we must
- // calculate the outside area
- if ( !EqualRect( &aSrcRect, &aTempRect3 ) )
- {
- ImplCalcOutSideRgn( aSrcRect,
- aTempRect3.left, aTempRect3.top,
- aTempRect3.right, aTempRect3.bottom,
- hInvalidateRgn );
- }
- }
- // retrieve the top-most (z-order) child window
- hWnd = GetWindow( GetDesktopWindow(), GW_CHILD );
- while ( hWnd )
- {
- if ( hWnd == hWndTopWindow )
- break;
- if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) )
- {
- GetWindowRect( hWnd, &aTempRect );
- if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) )
- {
- // hWnd covers part or all of aSrcRect
- if ( !hInvalidateRgn )
- hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect );
-
- // get full bounding box of hWnd
- hTempRgn = CreateRectRgnIndirect( &aTempRect );
-
- // get region of hWnd (the window may be shaped)
- if ( !hTempRgn2 )
- hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 );
- int nRgnType = GetWindowRgn( hWnd, hTempRgn2 );
- if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
- {
- // convert window region to screen coordinates
- OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top );
- // and intersect with the window's bounding box
- CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND );
- }
- // finally compute that part of aSrcRect which is not covered by any parts of hWnd
- CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
- }
- }
- // retrieve the next window in the z-order, i.e. the window below hwnd
- hWnd = GetWindow( hWnd, GW_HWNDNEXT );
- }
- if ( hTempRgn2 )
- DeleteRegion( hTempRgn2 );
- if ( hInvalidateRgn )
- {
- // hInvalidateRgn contains the fully visible parts of the original srcRect
- hTempRgn = CreateRectRgnIndirect( &aSrcRect );
- // substract it from the original rect to get the occluded parts
- int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF );
- DeleteRegion( hTempRgn );
-
- if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
- {
- // move the occluded parts to the destination pos
- int nOffX = (int)(nDestX-nSrcX);
- int nOffY = (int)(nDestY-nSrcY);
- OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y );
-
- // by excluding hInvalidateRgn from the system's clip region
- // we will prevent bitblt from copying useless data
- // epsecially now shadows from overlapping windows will appear (#i36344)
- hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 );
- nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn );
-
- bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate
- ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF );
- }
- }
- }
- }
-
- BitBlt( getHDC(),
- (int)nDestX, (int)nDestY,
- (int)nSrcWidth, (int)nSrcHeight,
- getHDC(),
- (int)nSrcX, (int)nSrcY,
- SRCCOPY );
-
- if( bRestoreClipRgn )
- {
- // restore old clip region
- if( nOldClipRgnType != ERROR )
- SelectClipRgn( getHDC(), hOldClipRgn);
- DeleteRegion( hOldClipRgn );
-
- // invalidate regions that were not copied
- bool bInvalidate = true;
-
- // Combine Invalidate vcl::Region with existing ClipRegion
- HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 );
- if ( GetClipRgn( getHDC(), hTempRgn ) == 1 )
- {
- int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND );
- if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) )
- bInvalidate = false;
- }
- DeleteRegion( hTempRgn );
-
- if ( bInvalidate )
- {
- InvalidateRgn( mhWnd, hInvalidateRgn, TRUE );
- // here we only initiate an update if this is the MainThread,
- // so that there is no deadlock when handling the Paint event,
- // as the SolarMutex is already held by this Thread
- SalData* pSalData = GetSalData();
- DWORD nCurThreadId = GetCurrentThreadId();
- if ( pSalData->mnAppThreadId == nCurThreadId )
- UpdateWindow( mhWnd );
- }
-
- DeleteRegion( hInvalidateRgn );
- }
-
-}
-
-void ImplDrawBitmap( HDC hDC,
- const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap,
- bool bPrinter, int nDrawMode )
-{
- if( hDC )
- {
- HGLOBAL hDrawDIB;
- HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
- WinSalBitmap* pTmpSalBmp = NULL;
- bool bPrintDDB = ( bPrinter && hDrawDDB );
-
- if( bPrintDDB )
- {
- pTmpSalBmp = new WinSalBitmap;
- pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
- hDrawDIB = pTmpSalBmp->ImplGethDIB();
- }
- else
- hDrawDIB = rSalBitmap.ImplGethDIB();
-
- if( hDrawDIB )
- {
- PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
- PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
- PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
- rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
- const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
-
- StretchDIBits( hDC,
- (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
- (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
- (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY),
- (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
- pBits, pBI, DIB_RGB_COLORS, nDrawMode );
-
- GlobalUnlock( hDrawDIB );
- SetStretchBltMode( hDC, nOldStretchMode );
- }
- else if( hDrawDDB && !bPrintDDB )
- {
- HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB );
- COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF);
- COLORREF nOldTextColor = RGB(0,0,0);
- bool bMono = ( rSalBitmap.GetBitCount() == 1 );
-
- if( bMono )
- {
- COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF );
- COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 );
- //fdo#33455 handle 1 bit depth pngs with palette entries
- //to set fore/back colors
- if (const BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(true))
- {
- const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
- if (rPalette.GetEntryCount() == 2)
- {
- SalColor nCol;
- nCol = ImplColorToSal(rPalette[0]);
- nTextColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
- nCol = ImplColorToSal(rPalette[1]);
- nBkColor = RGB( SALCOLOR_RED(nCol), SALCOLOR_GREEN(nCol), SALCOLOR_BLUE(nCol) );
- }
- }
- nOldBkColor = SetBkColor( hDC, nBkColor );
- nOldTextColor = ::SetTextColor( hDC, nTextColor );
- }
-
- if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
- (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) )
- {
- BitBlt( hDC,
- (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
- (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
- hBmpDC,
- (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
- nDrawMode );
- }
- else
- {
- const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
-
- StretchBlt( hDC,
- (int)rPosAry.mnDestX, (int)rPosAry.mnDestY,
- (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight,
- hBmpDC,
- (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
- (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight,
- nDrawMode );
-
- SetStretchBltMode( hDC, nOldStretchMode );
- }
-
- if( bMono )
- {
- SetBkColor( hDC, nOldBkColor );
- ::SetTextColor( hDC, nOldTextColor );
- }
-
- ImplReleaseCachedDC( CACHED_HDC_DRAW );
- }
-
- if( bPrintDDB )
- delete pTmpSalBmp;
- }
+ mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY,
+ nSrcWidth, nSrcHeight, nFlags );
}
void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap)
{
- bool bTryDirectPaint(!mbPrinter && !mbXORMode);
-
- if(bTryDirectPaint)
- {
- // only paint direct when no scaling and no MapMode, else the
- // more expensive conversions may be done for short-time Bitmap/BitmapEx
- // used for buffering only
- if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
- {
- bTryDirectPaint = false;
- }
- }
-
- // try to draw using GdiPlus directly
- if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap))
- {
- return;
- }
-
- // fall back old stuff
- ImplDrawBitmap(getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap),
- mbPrinter,
- mbXORMode ? SRCINVERT : SRCCOPY );
+ mpImpl->drawBitmap( rPosAry, rSalBitmap );
}
void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap,
SalColor nTransparentColor )
{
- DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
-
- const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
-
- WinSalBitmap* pMask = new WinSalBitmap;
- const Point aPoint;
- const Size aSize( rSalBitmap.GetSize() );
- HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL );
- HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap );
- const BYTE cRed = SALCOLOR_RED( nTransparentColor );
- const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor );
- const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor );
-
- if( rSalBitmap.ImplGethDDB() )
- {
- HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() );
- COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
-
- BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
-
- SetBkColor( hSrcDC, aOldCol );
- ImplReleaseCachedDC( CACHED_HDC_2 );
- }
- else
- {
- WinSalBitmap* pTmpSalBmp = new WinSalBitmap;
-
- if( pTmpSalBmp->Create( rSalBitmap, this ) )
- {
- HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() );
- COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
-
- BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
-
- SetBkColor( hSrcDC, aOldCol );
- ImplReleaseCachedDC( CACHED_HDC_2 );
- }
-
- delete pTmpSalBmp;
- }
-
- ImplReleaseCachedDC( CACHED_HDC_1 );
-
- // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE )
- if( pMask->Create( hMaskBitmap, FALSE, FALSE ) )
- drawBitmap( rPosAry, rSalBitmap, *pMask );
-
- delete pMask;
+ mpImpl->drawBitmap( rPosAry, rSSalBitmap, nTransparentColor );
}
void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap,
const SalBitmap& rSTransparentBitmap )
{
- DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
- bool bTryDirectPaint(!mbPrinter && !mbXORMode);
-
- if(bTryDirectPaint)
- {
- // only paint direct when no scaling and no MapMode, else the
- // more expensive conversions may be done for short-time Bitmap/BitmapEx
- // used for buffering only
- if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
- {
- bTryDirectPaint = false;
- }
- }
-
- // try to draw using GdiPlus directly
- if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap))
- {
- return;
- }
-
- const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
- const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap);
-
- SalTwoRect aPosAry = rPosAry;
- int nDstX = (int)aPosAry.mnDestX;
- int nDstY = (int)aPosAry.mnDestY;
- int nDstWidth = (int)aPosAry.mnDestWidth;
- int nDstHeight = (int)aPosAry.mnDestHeight;
- HDC hDC = getHDC();
- HBITMAP hMemBitmap = 0;
- HBITMAP hMaskBitmap = 0;
-
- if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) )
- {
- hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
- hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
- }
-
- HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap );
- HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap );
-
- aPosAry.mnDestX = aPosAry.mnDestY = 0;
- BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY );
-
- // WIN/WNT seems to have a minor problem mapping the correct color of the
- // mask to the palette if we draw the DIB directly ==> draw DDB
- if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
- {
- WinSalBitmap aTmp;
-
- if( aTmp.Create( rTransparentBitmap, this ) )
- ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY );
- }
- else
- ImplDrawBitmap( hMaskDC, aPosAry, rTransparentBitmap, FALSE, SRCCOPY );
-
- // now MemDC contains background, MaskDC the transparency mask
-
- // #105055# Respect XOR mode
- if( mbXORMode )
- {
- ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE );
- // now MaskDC contains the bitmap area with black background
- BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT );
- // now MemDC contains background XORed bitmap area ontop
- }
- else
- {
- BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND );
- // now MemDC contains background with masked-out bitmap area
- ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE );
- // now MaskDC contains the bitmap area with black background
- BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT );
- // now MemDC contains background and bitmap merged together
- }
- // copy to output DC
- BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY );
-
- ImplReleaseCachedDC( CACHED_HDC_1 );
- ImplReleaseCachedDC( CACHED_HDC_2 );
-
- // hMemBitmap != 0 ==> hMaskBitmap != 0
- if( hMemBitmap )
- {
- DeleteObject( hMemBitmap );
- DeleteObject( hMaskBitmap );
- }
+ mpImpl->drawBitmap( rPosAry, rSSalBitmap, rSTransparentBitmap );
}
bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
long nHeight, sal_uInt8 nTransparency )
{
- if( mbPen || !mbBrush || mbXORMode )
- return false; // can only perform solid fills without XOR.
-
- HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, 0 );
- SetPixel( hMemDC, (int)0, (int)0, mnBrushColor );
-
- BLENDFUNCTION aFunc = {
- AC_SRC_OVER,
- 0,
- sal::static_int_cast<sal_uInt8>(255 - 255L*nTransparency/100),
- 0
- };
-
- // hMemDC contains a 1x1 bitmap of the right color - stretch-blit
- // that to dest hdc
- bool bRet = AlphaBlend( getHDC(), nX, nY, nWidth, nHeight,
- hMemDC, 0,0,1,1,
- aFunc ) == TRUE;
-
- ImplReleaseCachedDC( CACHED_HDC_1 );
-
- return bRet;
+ return mpImpl->drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
}
void WinSalGraphics::drawMask( const SalTwoRect& rPosAry,
const SalBitmap& rSSalBitmap,
SalColor nMaskColor )
{
- DBG_ASSERT( !mbPrinter, "No transparency print possible!" );
-
- const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
-
- SalTwoRect aPosAry = rPosAry;
- const BYTE cRed = SALCOLOR_RED( nMaskColor );
- const BYTE cGreen = SALCOLOR_GREEN( nMaskColor );
- const BYTE cBlue = SALCOLOR_BLUE( nMaskColor );
- HDC hDC = getHDC();
- HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) );
- HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush );
-
- // WIN/WNT seems to have a minor problem mapping the correct color of the
- // mask to the palette if we draw the DIB directly ==> draw DDB
- if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
- {
- WinSalBitmap aTmp;
-
- if( aTmp.Create( rSalBitmap, this ) )
- ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL );
- }
- else
- ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
-
- SelectBrush( hDC, hOldBrush );
- DeleteBrush( hMaskBrush );
+ mpImpl->drawMask( rPosAry, rSSalBitmap, nMaskColor );
}
SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
{
- DBG_ASSERT( !mbPrinter, "No ::GetBitmap() from printer possible!" );
-
- WinSalBitmap* pSalBitmap = NULL;
-
- nDX = labs( nDX );
- nDY = labs( nDY );
-
- HDC hDC = getHDC();
- HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
- HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
- bool bRet;
-
- bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY ) ? TRUE : FALSE;
- ImplReleaseCachedDC( CACHED_HDC_1 );
-
- if( bRet )
- {
- pSalBitmap = new WinSalBitmap;
-
- if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
- {
- delete pSalBitmap;
- pSalBitmap = NULL;
- }
- }
- else
- {
- // #124826# avoid resource leak ! happens when runing without desktop access (remote desktop, service, may be screensavers)
- DeleteBitmap( hBmpBitmap );
- }
-
- return pSalBitmap;
+ return mpImpl->getBitmap( nX, nY, nDX, nDY );
}
SalColor WinSalGraphics::getPixel( long nX, long nY )
{
- COLORREF aWinCol = ::GetPixel( getHDC(), (int) nX, (int) nY );
-
- if ( CLR_INVALID == aWinCol )
- return MAKE_SALCOLOR( 0, 0, 0 );
- else
- return MAKE_SALCOLOR( GetRValue( aWinCol ),
- GetGValue( aWinCol ),
- GetBValue( aWinCol ) );
+ return mpImpl->getPixel( nX, nY );
}
void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
{
- if ( nFlags & SAL_INVERT_TRACKFRAME )
- {
- HPEN hDotPen = CreatePen( PS_DOT, 0, 0 );
- HPEN hOldPen = SelectPen( getHDC(), hDotPen );
- HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) );
- int nOldROP = SetROP2( getHDC(), R2_NOT );
-
- WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
-
- SetROP2( getHDC(), nOldROP );
- SelectPen( getHDC(), hOldPen );
- SelectBrush( getHDC(), hOldBrush );
- DeletePen( hDotPen );
- }
- else if ( nFlags & SAL_INVERT_50 )
- {
- SalData* pSalData = GetSalData();
- if ( !pSalData->mh50Brush )
- {
- if ( !pSalData->mh50Bmp )
- pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
- pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
- }
-
- COLORREF nOldTextColor = ::SetTextColor( getHDC(), 0 );
- HBRUSH hOldBrush = SelectBrush( getHDC(), pSalData->mh50Brush );
- PatBlt( getHDC(), nX, nY, nWidth, nHeight, PATINVERT );
- ::SetTextColor( getHDC(), nOldTextColor );
- SelectBrush( getHDC(), hOldBrush );
- }
- else
- {
- RECT aRect;
- aRect.left = (int)nX;
- aRect.top = (int)nY;
- aRect.right = (int)nX+nWidth;
- aRect.bottom = (int)nY+nHeight;
- ::InvertRect( getHDC(), &aRect );
- }
+ mpImpl->invert( nX, nY, nWidth, nHeight, nFlags );
}
void WinSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
{
- HPEN hPen;
- HPEN hOldPen;
- HBRUSH hBrush;
- HBRUSH hOldBrush = 0;
- COLORREF nOldTextColor RGB(0,0,0);
- int nOldROP = SetROP2( getHDC(), R2_NOT );
-
- if ( nSalFlags & SAL_INVERT_TRACKFRAME )
- hPen = CreatePen( PS_DOT, 0, 0 );
- else
- {
-
- if ( nSalFlags & SAL_INVERT_50 )
- {
- SalData* pSalData = GetSalData();
- if ( !pSalData->mh50Brush )
- {
- if ( !pSalData->mh50Bmp )
- pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
- pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
- }
-
- hBrush = pSalData->mh50Brush;
- }
- else
- hBrush = GetStockBrush( BLACK_BRUSH );
-
- hPen = GetStockPen( NULL_PEN );
- nOldTextColor = ::SetTextColor( getHDC(), 0 );
- hOldBrush = SelectBrush( getHDC(), hBrush );
- }
- hOldPen = SelectPen( getHDC(), hPen );
-
- POINT* pWinPtAry;
- // for NT, we can handover the array directly
- DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
- "WinSalGraphics::DrawPolyLine(): POINT != SalPoint" );
-
- pWinPtAry = (POINT*)pPtAry;
- // for Windows 95 and its maximum number of points
- if ( nSalFlags & SAL_INVERT_TRACKFRAME )
- {
- if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
- }
- else
- {
- if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
- WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS );
- }
-
- SetROP2( getHDC(), nOldROP );
- SelectPen( getHDC(), hOldPen );
-
- if ( nSalFlags & SAL_INVERT_TRACKFRAME )
- DeletePen( hPen );
- else
- {
- ::SetTextColor( getHDC(), nOldTextColor );
- SelectBrush( getHDC(), hOldBrush );
- }
+ mpImpl->invert( nPoints, pPtAry, nSalFlags );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx
index 1dc4f05a088a..65dbdd84acec 100644
--- a/vcl/win/source/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx
@@ -25,195 +25,11 @@
#include <win/salgdi.h>
#include <win/salbmp.h>
-#if defined _MSC_VER
-#ifndef min
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef max
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-#endif
-
-#if defined _MSC_VER
-#pragma warning(push, 1)
-#endif
-
-#ifdef __MINGW32__
-#ifdef GetObject
-#undef GetObject
-#endif
-#define GetObject GetObjectA
-#endif
-
-#include <gdiplus.h>
-#include <gdiplusenums.h>
-#include <gdipluscolor.h>
-
-#ifdef __MINGW32__
-#ifdef GetObject
-#undef GetObject
-#endif
-#endif
-
-#if defined _MSC_VER
-#pragma warning(pop)
-#endif
-
-#include <basegfx/polygon/b2dpolygon.hxx>
-
-void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
-{
- sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- Gdiplus::DllExports::GdipAddPathBezier(pPath,
- aCurr.getX(), aCurr.getY(),
- aCa.getX(), aCa.getY(),
- aCb.getX(), aCb.getY(),
- aNext.getX(), aNext.getY());
- }
- else
- {
- Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
-
- if(bNoLineJoin)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath);
- }
- }
- }
- }
-}
-
-void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
-{
- sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- Gdiplus::DllExports::GdipAddPathBezier(
- pPath,
- aCurr.getX(), aCurr.getY(),
- aCa.getX(), aCa.getY(),
- aCb.getX(), aCb.getY(),
- aNext.getX(), aNext.getY());
- }
- else
- {
- Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
-
- if(bNoLineJoin)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath);
- }
- }
- }
- }
-}
+#include "gdiimpl.hxx"
bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
{
- const sal_uInt32 nCount(rPolyPolygon.count());
-
- if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
- {
- Gdiplus::GpGraphics *pGraphics = NULL;
- Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics);
- const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
- Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
- Gdiplus::GpSolidFill *pTestBrush;
- Gdiplus::DllExports::GdipCreateSolidFill(aTestColor.GetValue(), &pTestBrush);
- Gdiplus::GpPath *pPath = NULL;
- Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
-
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- if(0 != a)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath); // #i101491# not needed for first run
- }
-
- impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolyPolygon.getB2DPolygon(a), false);
- Gdiplus::DllExports::GdipClosePathFigure(pPath);
- }
-
- if(getAntiAliasB2DDraw())
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
- }
-
- if(mbPrinter)
- {
- // #i121591#
- // Normally GdiPlus should not be used for printing at all since printers cannot
- // print transparent filled polygon geometry and normally this does not happen
- // since OutputDevice::RemoveTransparenciesFromMetaFile is used as preparation
- // and no transparent parts should remain for printing. But this can be overridden
- // by the user and thus happens. This call can only come (currently) from
- // OutputDevice::DrawTransparent, see comments there with the same TaskID.
- // If it is used, the mapping for the printer is wrong and needs to be corrected. I
- // checked that there is *no* transformation set and estimated that a stable factor
- // dependent of the printer's DPI is used. Create and set a transformation here to
- // correct this.
- Gdiplus::REAL aDpiX;
- Gdiplus::DllExports::GdipGetDpiX(pGraphics, &aDpiX);
- Gdiplus::REAL aDpiY;
- Gdiplus::DllExports::GdipGetDpiY(pGraphics, &aDpiY);
-
- Gdiplus::DllExports::GdipResetWorldTransform(pGraphics);
- Gdiplus::DllExports::GdipScaleWorldTransform(pGraphics, Gdiplus::REAL(100.0) / aDpiX, Gdiplus::REAL(100.0) / aDpiY, Gdiplus::MatrixOrderAppend);
- }
-
- Gdiplus::DllExports::GdipFillPath(pGraphics, pTestBrush, pPath);
-
- Gdiplus::DllExports::GdipDeletePath(pPath);
- Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
- }
-
- return true;
+ return mpImpl->drawPolyPolygon( rPolyPolygon, fTransparency );
}
bool WinSalGraphics::drawPolyLine(
@@ -223,199 +39,8 @@ bool WinSalGraphics::drawPolyLine(
basegfx::B2DLineJoin eLineJoin,
com::sun::star::drawing::LineCap eLineCap)
{
- const sal_uInt32 nCount(rPolygon.count());
-
- if(mbPen && nCount)
- {
- Gdiplus::GpGraphics *pGraphics = NULL;
- Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics);
- const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
- Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
- Gdiplus::GpPen *pTestPen = NULL;
- Gdiplus::DllExports::GdipCreatePen1(aTestColor.GetValue(), Gdiplus::REAL(rLineWidths.getX()), Gdiplus::UnitWorld, &pTestPen);
- Gdiplus::GpPath *pPath;
- Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
- bool bNoLineJoin(false);
-
- switch(eLineJoin)
- {
- default : // basegfx::B2DLINEJOIN_NONE :
- {
- if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
- {
- bNoLineJoin = true;
- }
- break;
- }
- case basegfx::B2DLINEJOIN_BEVEL :
- {
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinBevel);
- break;
- }
- case basegfx::B2DLINEJOIN_MIDDLE :
- case basegfx::B2DLINEJOIN_MITER :
- {
- const Gdiplus::REAL aMiterLimit(15.0);
- Gdiplus::DllExports::GdipSetPenMiterLimit(pTestPen, aMiterLimit);
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinMiter);
- break;
- }
- case basegfx::B2DLINEJOIN_ROUND :
- {
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinRound);
- break;
- }
- }
-
- switch(eLineCap)
- {
- default: /*com::sun::star::drawing::LineCap_BUTT*/
- {
- // nothing to do
- break;
- }
- case com::sun::star::drawing::LineCap_ROUND:
- {
- Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapRound);
- Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapRound);
- break;
- }
- case com::sun::star::drawing::LineCap_SQUARE:
- {
- Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapSquare);
- Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapSquare);
- break;
- }
- }
-
- if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
- {
- impAddB2DPolygonToGDIPlusGraphicsPathInteger(pPath, rPolygon, bNoLineJoin);
- }
- else
- {
- impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolygon, bNoLineJoin);
- }
-
- if(rPolygon.isClosed() && !bNoLineJoin)
- {
- // #i101491# needed to create the correct line joins
- Gdiplus::DllExports::GdipClosePathFigure(pPath);
- }
-
- if(getAntiAliasB2DDraw())
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
- }
-
- Gdiplus::DllExports::GdipDrawPath(pGraphics, pTestPen, pPath);
-
- Gdiplus::DllExports::GdipDeletePath(pPath);
- Gdiplus::DllExports::GdipDeletePen(pTestPen);
- Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
- }
-
- return true;
-}
-
-void paintToGdiPlus(
- Gdiplus::Graphics& rGraphics,
- const SalTwoRect& rTR,
- Gdiplus::Bitmap& rBitmap)
-{
- // only parts of source are used
- Gdiplus::PointF aDestPoints[3];
- Gdiplus::ImageAttributes aAttributes;
-
- // define target region as paralellogram
- aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX);
- aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY);
- aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth);
- aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY);
- aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX);
- aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight);
-
- aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
-
- rGraphics.DrawImage(
- &rBitmap,
- aDestPoints,
- 3,
- Gdiplus::REAL(rTR.mnSrcX),
- Gdiplus::REAL(rTR.mnSrcY),
- Gdiplus::REAL(rTR.mnSrcWidth),
- Gdiplus::REAL(rTR.mnSrcHeight),
- Gdiplus::UnitPixel,
- &aAttributes,
- 0,
- 0);
-}
-
-void setInterpolationMode(
- Gdiplus::Graphics& rGraphics,
- const long& rSrcWidth,
- const long& rDestWidth,
- const long& rSrcHeight,
- const long& rDestHeight)
-{
- const bool bSameWidth(rSrcWidth == rDestWidth);
- const bool bSameHeight(rSrcHeight == rDestHeight);
-
- if(bSameWidth && bSameHeight)
- {
-#ifdef __MINGW32__
- //Gdiplus::InterpolationModeInvalid is missing on mingw
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
-#else
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid);
-#endif
- }
- else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight)
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
- }
- else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight)
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
- }
- else
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
- }
-}
-
-bool WinSalGraphics::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap)
-{
- if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
- {
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
-
- if(aARGB.get())
- {
- Gdiplus::Graphics aGraphics(getHDC());
-
- setInterpolationMode(
- aGraphics,
- rTR.mnSrcWidth,
- rTR.mnDestWidth,
- rTR.mnSrcHeight,
- rTR.mnDestHeight);
-
- paintToGdiPlus(
- aGraphics,
- rTR,
- *aARGB.get());
-
- return true;
- }
- }
-
- return false;
+ return mpImpl->drawPolyLine(rPolygon, fTransparency, rLineWidths,
+ eLineJoin, eLineCap);
}
bool WinSalGraphics::drawAlphaBitmap(
@@ -423,33 +48,7 @@ bool WinSalGraphics::drawAlphaBitmap(
const SalBitmap& rSrcBitmap,
const SalBitmap& rAlphaBmp)
{
- if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
- {
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
- const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha));
-
- if(aARGB.get())
- {
- Gdiplus::Graphics aGraphics(getHDC());
-
- setInterpolationMode(
- aGraphics,
- rTR.mnSrcWidth,
- rTR.mnDestWidth,
- rTR.mnSrcHeight,
- rTR.mnDestHeight);
-
- paintToGdiPlus(
- aGraphics,
- rTR,
- *aARGB.get());
-
- return true;
- }
- }
-
- return false;
+ return mpImpl->drawAlphaBitmap(rTR, rSrcBitmap, rAlphaBmp);
}
bool WinSalGraphics::drawTransformedBitmap(
@@ -459,62 +58,8 @@ bool WinSalGraphics::drawTransformedBitmap(
const SalBitmap& rSourceBitmap,
const SalBitmap* pAlphaBitmap)
{
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap);
- const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
-
- if(aARGB.get())
- {
- const long nSrcWidth(aARGB->GetWidth());
- const long nSrcHeight(aARGB->GetHeight());
-
- if(nSrcWidth && nSrcHeight)
- {
- const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength()));
- const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength()));
-
- if(nDestWidth && nDestHeight)
- {
- Gdiplus::Graphics aGraphics(getHDC());
- Gdiplus::PointF aDestPoints[3];
- Gdiplus::ImageAttributes aAttributes;
-
- setInterpolationMode(
- aGraphics,
- nSrcWidth,
- nDestWidth,
- nSrcHeight,
- nDestHeight);
-
- // this mode is only capable of drawing the whole bitmap to a paralellogram
- aDestPoints[0].X = Gdiplus::REAL(rNull.getX());
- aDestPoints[0].Y = Gdiplus::REAL(rNull.getY());
- aDestPoints[1].X = Gdiplus::REAL(rX.getX());
- aDestPoints[1].Y = Gdiplus::REAL(rX.getY());
- aDestPoints[2].X = Gdiplus::REAL(rY.getX());
- aDestPoints[2].Y = Gdiplus::REAL(rY.getY());
-
- aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
-
- aGraphics.DrawImage(
- aARGB.get(),
- aDestPoints,
- 3,
- Gdiplus::REAL(0.0),
- Gdiplus::REAL(0.0),
- Gdiplus::REAL(nSrcWidth),
- Gdiplus::REAL(nSrcHeight),
- Gdiplus::UnitPixel,
- &aAttributes,
- 0,
- 0);
- }
- }
-
- return true;
- }
-
- return false;
+ return mpImpl->drawTransformedBitmap(rNull, rX, rY,
+ rSourceBitmap, pAlphaBitmap);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx
index 6d6b8ea49f01..ad22b4e817a2 100644
--- a/vcl/win/source/gdi/salprn.cxx
+++ b/vcl/win/source/gdi/salprn.cxx
@@ -1045,15 +1045,10 @@ static HDC ImplCreateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetup
static WinSalGraphics* ImplCreateSalPrnGraphics( HDC hDC )
{
- WinSalGraphics* pGraphics = new WinSalGraphics;
+ WinSalGraphics* pGraphics = new WinSalGraphics(WinSalGraphics::PRINTER, false, 0);
pGraphics->SetLayout( 0 );
pGraphics->setHDC(hDC);
- pGraphics->mhWnd = 0;
- pGraphics->mbPrinter = TRUE;
- pGraphics->mbVirDev = FALSE;
- pGraphics->mbWindow = FALSE;
- pGraphics->mbScreen = FALSE;
- ImplSalInitGraphics( pGraphics );
+ pGraphics->InitGraphics();
return pGraphics;
}
@@ -1065,7 +1060,7 @@ static bool ImplUpdateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetu
if ( pPrinter->mpGraphics )
{
- ImplSalDeInitGraphics( pPrinter->mpGraphics );
+ pPrinter->mpGraphics->DeInitGraphics();
DeleteDC( pPrinter->mpGraphics->getHDC() );
delete pPrinter->mpGraphics;
}
@@ -1129,7 +1124,7 @@ WinSalInfoPrinter::~WinSalInfoPrinter()
{
if ( mpGraphics )
{
- ImplSalDeInitGraphics( mpGraphics );
+ mpGraphics->DeInitGraphics();
DeleteDC( mpGraphics->getHDC() );
delete mpGraphics;
}
@@ -1412,7 +1407,7 @@ WinSalPrinter::~WinSalPrinter()
{
if ( mpGraphics )
{
- ImplSalDeInitGraphics( mpGraphics );
+ mpGraphics->DeInitGraphics();
delete mpGraphics;
}
@@ -1587,7 +1582,7 @@ bool WinSalPrinter::EndJob()
{
if ( mpGraphics )
{
- ImplSalDeInitGraphics( mpGraphics );
+ mpGraphics->DeInitGraphics();
delete mpGraphics;
mpGraphics = NULL;
}
@@ -1650,7 +1645,7 @@ void ImplSalPrinterAbortJobAsync( HDC hPrnDC )
{
if ( pPrinter->mpGraphics )
{
- ImplSalDeInitGraphics( pPrinter->mpGraphics );
+ pPrinter->mpGraphics->DeInitGraphics();
delete pPrinter->mpGraphics;
pPrinter->mpGraphics = NULL;
}
@@ -1710,7 +1705,7 @@ bool WinSalPrinter::EndPage()
HDC hDC = mhDC;
if ( hDC && mpGraphics )
{
- ImplSalDeInitGraphics( mpGraphics );
+ mpGraphics->DeInitGraphics();
delete mpGraphics;
mpGraphics = NULL;
}
diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx
index fec719b1aaa1..2269debcd1a8 100644
--- a/vcl/win/source/gdi/salvd.cxx
+++ b/vcl/win/source/gdi/salvd.cxx
@@ -104,20 +104,15 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
{
WinSalVirtualDevice* pVDev = new WinSalVirtualDevice;
SalData* pSalData = GetSalData();
- WinSalGraphics* pVirGraphics = new WinSalGraphics;
+ WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, pGraphics->isScreen(), 0);
pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
pVirGraphics->setHDC(hDC);
- pVirGraphics->mhWnd = 0;
- pVirGraphics->mbPrinter = FALSE;
- pVirGraphics->mbVirDev = TRUE;
- pVirGraphics->mbWindow = FALSE;
- pVirGraphics->mbScreen = pGraphics->mbScreen;
- if ( pSalData->mhDitherPal && pVirGraphics->mbScreen )
+ if ( pSalData->mhDitherPal && pVirGraphics->isScreen() )
{
- pVirGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ pVirGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
RealizePalette( hDC );
}
- ImplSalInitGraphics( pVirGraphics );
+ pVirGraphics->InitGraphics();
pVDev->setHDC(hDC);
pVDev->mhBmp = hBmp;
@@ -168,9 +163,9 @@ WinSalVirtualDevice::~WinSalVirtualDevice()
*ppVirDev = mpNext;
// destroy saved DC
- if( mpGraphics->mhDefPal )
- SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE );
- ImplSalDeInitGraphics( mpGraphics );
+ if( mpGraphics->getDefPal() )
+ SelectPalette( mpGraphics->getHDC(), mpGraphics->getDefPal(), TRUE );
+ mpGraphics->InitGraphics();
if( mhDefBmp )
SelectBitmap( mpGraphics->getHDC(), mhDefBmp );
if( !mbForeignDC )
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
index 2de8d5855a73..9dd008bb5261 100644
--- a/vcl/win/source/window/salframe.cxx
+++ b/vcl/win/source/window/salframe.cxx
@@ -932,9 +932,9 @@ WinSalFrame::~WinSalFrame()
// destroy saved DC
if ( mpGraphics )
{
- if ( mpGraphics->mhDefPal )
- SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE );
- ImplSalDeInitGraphics( mpGraphics );
+ if ( mpGraphics->getDefPal() )
+ SelectPalette( mpGraphics->getHDC(), mpGraphics->getDefPal(), TRUE );
+ mpGraphics->DeInitGraphics();
ReleaseDC( mhWnd, mpGraphics->getHDC() );
delete mpGraphics;
mpGraphics = NULL;
@@ -983,13 +983,8 @@ SalGraphics* WinSalFrame::AcquireGraphics()
if ( !mpGraphics2 )
{
- mpGraphics2 = new WinSalGraphics;
+ mpGraphics2 = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd);
mpGraphics2->setHDC(0);
- mpGraphics2->mhWnd = mhWnd;
- mpGraphics2->mbPrinter = FALSE;
- mpGraphics2->mbVirDev = FALSE;
- mpGraphics2->mbWindow = TRUE;
- mpGraphics2->mbScreen = TRUE;
}
HDC hDC = (HDC)(sal_IntPtr)SendMessageW( pSalData->mpFirstInstance->mhComWnd,
@@ -1000,10 +995,10 @@ SalGraphics* WinSalFrame::AcquireGraphics()
mpGraphics2->setHDC(hDC);
if ( pSalData->mhDitherPal )
{
- mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ mpGraphics2->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
RealizePalette( hDC );
}
- ImplSalInitGraphics( mpGraphics2 );
+ mpGraphics2->InitGraphics();
mbGraphics = TRUE;
pSalData->mnCacheDCInUse++;
@@ -1019,19 +1014,14 @@ SalGraphics* WinSalFrame::AcquireGraphics()
HDC hDC = GetDC( mhWnd );
if ( hDC )
{
- mpGraphics = new WinSalGraphics;
+ mpGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd);
mpGraphics->setHDC(hDC);
- mpGraphics->mhWnd = mhWnd;
- mpGraphics->mbPrinter = FALSE;
- mpGraphics->mbVirDev = FALSE;
- mpGraphics->mbWindow = TRUE;
- mpGraphics->mbScreen = TRUE;
if ( pSalData->mhDitherPal )
{
- mpGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ mpGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
RealizePalette( hDC );
}
- ImplSalInitGraphics( mpGraphics );
+ mpGraphics->InitGraphics();
mbGraphics = TRUE;
}
}
@@ -1049,9 +1039,9 @@ void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
if ( mpGraphics2->getHDC() )
{
SalData* pSalData = GetSalData();
- if ( mpGraphics2->mhDefPal )
- SelectPalette( mpGraphics2->getHDC(), mpGraphics2->mhDefPal, TRUE );
- ImplSalDeInitGraphics( mpGraphics2 );
+ if ( mpGraphics2->getDefPal() )
+ SelectPalette( mpGraphics2->getHDC(), mpGraphics2->getDefPal(), TRUE );
+ mpGraphics2->InitGraphics();
SendMessageW( pSalData->mpFirstInstance->mhComWnd,
SAL_MSG_RELEASEDC,
(WPARAM)mhWnd,
@@ -1499,9 +1489,9 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
// destroy saved DC
if ( pThis->mpGraphics )
{
- if ( pThis->mpGraphics->mhDefPal )
- SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->mhDefPal, TRUE );
- ImplSalDeInitGraphics( pThis->mpGraphics );
+ if ( pThis->mpGraphics->getDefPal() )
+ SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->getDefPal(), TRUE );
+ pThis->mpGraphics->InitGraphics();
ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() );
}
@@ -1520,7 +1510,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
{
if( pThis->mpGraphics2 )
{
- pThis->mpGraphics2->mhWnd = hWnd;
+ pThis->mpGraphics2->setHWND(hWnd);
if( bNeedCacheDC )
{
@@ -1533,10 +1523,10 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
pThis->mpGraphics2->setHDC(hDC);
if ( pSalData->mhDitherPal )
{
- pThis->mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ pThis->mpGraphics2->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
RealizePalette( hDC );
}
- ImplSalInitGraphics( pThis->mpGraphics2 );
+ pThis->mpGraphics2->InitGraphics();
// re-select saved gdi objects
if( hFont )
@@ -1558,14 +1548,14 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, bool bAs
if( pThis->mpGraphics )
{
// re-create DC
- pThis->mpGraphics->mhWnd = hWnd;
+ pThis->mpGraphics->setHWND(hWnd);
pThis->mpGraphics->setHDC( GetDC( hWnd ) );
if ( GetSalData()->mhDitherPal )
{
- pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE );
+ pThis->mpGraphics->setDefPal(SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE ));
RealizePalette( pThis->mpGraphics->getHDC() );
}
- ImplSalInitGraphics( pThis->mpGraphics );
+ pThis->mpGraphics->InitGraphics();
pThis->mbGraphics = TRUE;
}
}
@@ -3763,7 +3753,7 @@ static bool ImplHandlePaintMsg( HWND hWnd )
{
// clip-region must be reset, as we do not get a proper
// bounding-rectangle otherwise
- if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
+ if ( pFrame->mpGraphics && pFrame->mpGraphics->getRegion() )
SelectClipRgn( pFrame->mpGraphics->getHDC(), 0 );
// according to Window-Documentation one shall check first if
@@ -3779,10 +3769,10 @@ static bool ImplHandlePaintMsg( HWND hWnd )
// Paint
// reset ClipRegion
- if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
+ if ( pFrame->mpGraphics && pFrame->mpGraphics->getRegion() )
{
SelectClipRgn( pFrame->mpGraphics->getHDC(),
- pFrame->mpGraphics->mhRegion );
+ pFrame->mpGraphics->getRegion() );
}
if ( bMutex )
@@ -3801,10 +3791,10 @@ static bool ImplHandlePaintMsg( HWND hWnd )
else
{
// reset ClipRegion
- if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion )
+ if ( pFrame->mpGraphics && pFrame->mpGraphics->getRegion() )
{
SelectClipRgn( pFrame->mpGraphics->getHDC(),
- pFrame->mpGraphics->mhRegion );
+ pFrame->mpGraphics->getRegion() );
}
}
}
@@ -4157,7 +4147,7 @@ static void ImplHandleForcePalette( HWND hWnd )
if ( pFrame && pFrame->mpGraphics )
{
WinSalGraphics* pGraphics = pFrame->mpGraphics;
- if ( pGraphics && pGraphics->mhDefPal )
+ if ( pGraphics && pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(), hPal, FALSE );
if ( RealizePalette( pGraphics->getHDC() ) )
@@ -4220,10 +4210,10 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempVD )
{
pGraphics = pTempVD->mpGraphics;
- if ( pGraphics->mhDefPal )
+ if ( pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(),
- pGraphics->mhDefPal,
+ pGraphics->getDefPal(),
TRUE );
}
pTempVD = pTempVD->mpNext;
@@ -4232,10 +4222,10 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempFrame )
{
pGraphics = pTempFrame->mpGraphics;
- if ( pGraphics && pGraphics->mhDefPal )
+ if ( pGraphics && pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(),
- pGraphics->mhDefPal,
+ pGraphics->getDefPal(),
TRUE );
}
pTempFrame = pTempFrame->mpNextFrame;
@@ -4270,7 +4260,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempVD )
{
pGraphics = pTempVD->mpGraphics;
- if ( pGraphics->mhDefPal )
+ if ( pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(), hPal, TRUE );
RealizePalette( pGraphics->getHDC() );
@@ -4283,7 +4273,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
if ( pTempFrame != pFrame )
{
pGraphics = pTempFrame->mpGraphics;
- if ( pGraphics && pGraphics->mhDefPal )
+ if ( pGraphics && pGraphics->getDefPal() )
{
SelectPalette( pGraphics->getHDC(), hPal, TRUE );
if ( RealizePalette( pGraphics->getHDC() ) )
@@ -4300,7 +4290,7 @@ static LRESULT ImplHandlePalette( bool bFrame, HWND hWnd, UINT nMsg,
while ( pTempFrame )
{
pGraphics = pTempFrame->mpGraphics;
- if ( pGraphics && pGraphics->mhDefPal )
+ if ( pGraphics && pGraphics->getDefPal() )
{
InvalidateRect( pTempFrame->mhWnd, NULL, FALSE );
UpdateWindow( pTempFrame->mhWnd );
diff --git a/vcl/workben/icontest.cxx b/vcl/workben/icontest.cxx
index 543d1c7fad91..39c36865f13c 100644
--- a/vcl/workben/icontest.cxx
+++ b/vcl/workben/icontest.cxx
@@ -81,21 +81,6 @@ public:
virtual void Resize() SAL_OVERRIDE;
};
-class MyOpenGLWorkWindow : public MyWorkWindow
-{
-public:
- bool mbHaveTexture;
- OpenGLWindow *mpOpenGLWindow;
- GLuint mnTextureName;
- float mnTextureAspect;
-
- void LoadTexture();
-
- MyOpenGLWorkWindow( vcl::Window* pParent, WinBits nWinStyle );
-
- virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
-};
-
MyWorkWindow::MyWorkWindow( vcl::Window* pParent, WinBits nWinStyle )
: WorkWindow(pParent, nWinStyle)
, mpBitmap(NULL)
@@ -146,165 +131,6 @@ void MyWorkWindow::Paint( const Rectangle& rRect )
Invalidate( INVALIDATE_CHILDREN );
}
-MyOpenGLWorkWindow::MyOpenGLWorkWindow( vcl::Window* pParent, WinBits nWinStyle )
- : MyWorkWindow(pParent, nWinStyle)
- , mnTextureName(0)
- , mnTextureAspect(0)
-{
- mbHaveTexture = false;
- mpOpenGLWindow = new OpenGLWindow( this );
- mpOpenGLWindow->SetSizePixel( Size( WIDTH, HEIGHT ) );
- mpOpenGLWindow->Show();
- mpOpenGLWindow->EnableInput();
-}
-
-void MyOpenGLWorkWindow::LoadTexture()
-{
- mbHaveTexture = true;
-
- glEnable(GL_TEXTURE_2D);
- CHECK_GL_ERROR();
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- CHECK_GL_ERROR();
-
- glGenTextures( 1, &mnTextureName );
- CHECK_GL_ERROR();
-
- glBindTexture(GL_TEXTURE_2D, mnTextureName);
- CHECK_GL_ERROR();
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- CHECK_GL_ERROR();
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- CHECK_GL_ERROR();
-
- BitmapEx aBitmap( maGraphic.GetBitmapEx( ) );
- Size aBitmapSize( aBitmap.GetSizePixel() );
-
- GLint maxTexSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
- CHECK_GL_ERROR();
-
- SAL_INFO("vcl.icontest", "GL_MAX_TEXTURE_SIZE: " << maxTexSize);
-
- if (aBitmapSize.Width() > maxTexSize || aBitmapSize.Height() > maxTexSize)
- {
- Size aNewSize(aBitmapSize);
- if (aNewSize.Width() > maxTexSize)
- {
- aNewSize.setHeight(aNewSize.Height() * (((float) maxTexSize) / aNewSize.Width()));
- aNewSize.setWidth(maxTexSize);
- }
- if (aNewSize.Height() > maxTexSize)
- {
- aNewSize.setWidth(aNewSize.Width() * (((float) maxTexSize) / aNewSize.Height()));
- aNewSize.setHeight(maxTexSize);
- }
- SAL_INFO("vcl.icontest", "Scaling to " << aNewSize);
- aBitmap.Scale(aNewSize, BMP_SCALE_SUPER);
- aBitmapSize = aNewSize;
- }
-
- SAL_INFO("vcl.icontest", "GLEW_ARB_texture_non_power_of_two: " << (GLEW_ARB_texture_non_power_of_two ? "YES" : "NO"));
-
- GLsizei texWidth(aBitmapSize.Width()), texHeight(aBitmapSize.Height());
-
- mnTextureAspect = ((float) aBitmapSize.Width()) / aBitmapSize.Height();
-
- if (!GLEW_ARB_texture_non_power_of_two)
- {
- texWidth = texHeight = std::max(aBitmapSize.Width(), aBitmapSize.Height());
- if (!glm::isPowerOfTwo(texWidth))
- {
- texWidth = glm::powerOfTwoAbove(texWidth);
- texHeight = texWidth;
- }
-
- aBitmap.Expand(texWidth - aBitmapSize.Width(), texHeight - aBitmapSize.Height());
-
- mnTextureAspect = 1;
- }
-
- SAL_INFO("vcl.icontest", "Texture size: " << texWidth << "x" << texHeight);
-
- GLubyte *buffer = new GLubyte[texWidth * texHeight * 4];
- OpenGLHelper::ConvertBitmapExToRGBATextureBuffer( aBitmap, buffer, true );
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- texWidth, texHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE,
- buffer);
- CHECK_GL_ERROR();
-
- delete[] buffer;
-}
-
-void MyOpenGLWorkWindow::Paint( const Rectangle& )
-{
- std::cout << "==> Paint! "<< mnPaintCount++ << " (OpenGL) " << GetSizePixel() << " " << getTimeNow() - mnStartTime << std::endl;
- OpenGLContext& aCtx = mpOpenGLWindow->getContext();
- aCtx.requestLegacyContext();
- CHECK_GL_ERROR();
-
- if (!mbHaveTexture)
- LoadTexture();
-
- aCtx.setWinSize( Size( WIDTH+1, HEIGHT+1 ) );
- CHECK_GL_ERROR();
-
- aCtx.makeCurrent();
- CHECK_GL_ERROR();
-
- glViewport( 0, 0, WIDTH, HEIGHT );
- CHECK_GL_ERROR();
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- CHECK_GL_ERROR();
-
- glBindTexture(GL_TEXTURE_2D, mnTextureName);
- CHECK_GL_ERROR();
-
- glPushMatrix();
- CHECK_GL_ERROR();
-
- glTranslatef(-1, -1, 0);
- glScalef(2, 2, 2);
-
- if (mnTextureAspect >= ((float) WIDTH) / HEIGHT)
- glScalef(1, 1/mnTextureAspect, 1);
- else
- glScalef(1*mnTextureAspect, 1, 1);
- CHECK_GL_ERROR();
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex3f(0, 0, 0);
- glTexCoord2f(0, 1);
- glVertex3f(0, 1 + (0.1*sin(mnPaintCount/50.)), 0);
- glTexCoord2f(1, 1);
- glVertex3f(1 + (0.1*sin(mnPaintCount/60.)), 1 + (0.1*sin(mnPaintCount/50.)), 0);
- glTexCoord2f(1, 0);
- glVertex3f(1 + (0.1*sin(mnPaintCount/60.)), 0, 0);
- glEnd();
- CHECK_GL_ERROR();
-
- glPopMatrix();
- CHECK_GL_ERROR();
-
- aCtx.swapBuffers();
- CHECK_GL_ERROR();
-
- if (mnPaintCount == 100)
- Application::Quit();
-
- Invalidate( INVALIDATE_CHILDREN );
-}
-
void MyWorkWindow::Resize()
{
SAL_INFO("vcl.icontest", "Resize " << GetSizePixel());
@@ -345,18 +171,13 @@ void IconTestApp::Init()
int IconTestApp::Main()
{
- if (GetCommandLineParamCount() != 2 ||
- (GetCommandLineParam(0) != "vcl" &&
- GetCommandLineParam(0) != "opengl"))
+ if (GetCommandLineParamCount() != 1)
{
- fprintf(stderr, "Usage: imagetest [vcl|opengl] image\n");
+ fprintf(stderr, "Usage: imagetest <image>\n");
return EXIT_FAILURE;
}
- OUString sImageFile( GetCommandLineParam( 1 ) );
- if (GetCommandLineParam(0) == "vcl")
- DoItWithVcl( sImageFile );
- else
- DoItWithOpenGL( sImageFile );
+ OUString sImageFile( GetCommandLineParam( 0 ) );
+ DoItWithVcl( sImageFile );
return nRet;
}
@@ -391,37 +212,6 @@ void IconTestApp::DoItWithVcl( const OUString& sImageFile)
}
}
-void IconTestApp::DoItWithOpenGL(const OUString& sImageFile)
-{
- try
- {
- MyOpenGLWorkWindow *pWindow = new MyOpenGLWorkWindow( NULL, WB_APP | WB_STDWORK | WB_SIZEABLE | WB_CLOSEABLE | WB_CLIPCHILDREN );
-
- pWindow->SetText(OUString("OpenGL Image Test"));
-
- pWindow->LoadGraphic( sImageFile );
-
- Size aGraphicSize( pWindow->maGraphic.GetSizePixel() );
- float aspect = ((float) aGraphicSize.Width()) / aGraphicSize.Height();
- SAL_INFO("vcl.icontest", sImageFile << ": size: " << aGraphicSize << " aspect: " << aspect);
-
- pWindow->Hide();
- pWindow->Show();
-
- Execute();
- }
- catch (const uno::Exception &e)
- {
- fprintf(stderr, "fatal error: %s\n", OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
- nRet = EXIT_FAILURE;
- }
- catch (const std::exception &e)
- {
- fprintf(stderr, "fatal error: %s\n", e.what());
- nRet = EXIT_FAILURE;
- }
-}
-
void vclmain::createApplication()
{
static IconTestApp aApp;
diff --git a/vcl/workben/outdevgrind.cxx b/vcl/workben/outdevgrind.cxx
index 9b99ee3c1fa5..66763e0ad765 100644
--- a/vcl/workben/outdevgrind.cxx
+++ b/vcl/workben/outdevgrind.cxx
@@ -17,17 +17,16 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-// bootstrap stuff
-#include <rtl/bootstrap.hxx>
-#include <rtl/ustring.hxx>
-#include <comphelper/processfactory.hxx>
-#include <cppuhelper/servicefactory.hxx>
+#include <sal/main.h>
+#include <tools/extendapplicationenvironment.hxx>
+
#include <cppuhelper/bootstrap.hxx>
+#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/lang/XInitialization.hpp>
-#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
#include <vcl/dialog.hxx>
#include <vcl/outdev.hxx>
#include <vcl/virdev.hxx>
@@ -41,13 +40,14 @@
#include <vcl/gradient.hxx>
#include <vcl/lineinfo.hxx>
+#include <rtl/bootstrap.hxx>
+
#include <osl/time.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <stdio.h>
-#include <unistd.h>
using namespace ::com::sun::star;
@@ -110,6 +110,7 @@ void setupMethodStubs( functor_vector_type& res )
const OUString aString("This is a test");
const LineInfo aLineInfo(LINE_SOLID,5);
+#ifdef FIXME_VDEV
// unfortunately, VDevs have inaccessible copy constructors
static VirtualDevice aVDev;
static VirtualDevice aVDevBW(1);
@@ -121,6 +122,18 @@ void setupMethodStubs( functor_vector_type& res )
const Bitmap aBitmap( aVDev.GetBitmap(aPt1,aVDevSize) );
const Bitmap aBitmapBW( aVDevBW.GetBitmap(aPt1,aVDevSize) );
const Bitmap aBitmapAlien( aVDevSize, 8 );
+#else
+ BitmapEx aIntro;
+ rtl::Bootstrap::set("BRAND_BASE_DIR", ".");
+ if (Application::LoadBrandBitmap ("intro", aIntro))
+ Application::Abort( "Failed to load intro image, run inside program/" );
+
+ const Bitmap aBitmap( aIntro.GetBitmap() );
+ Bitmap aBitmapBW( aBitmap );
+ aBitmapBW.Filter( BMP_FILTER_EMBOSS_GREY );
+ Bitmap aBitmapAlien( Size( 100, 100 ), 8 );
+ aBitmapAlien.Erase( COL_RED );
+#endif
const BitmapEx aBitmapEx( aBitmap, aBitmapBW );
const BitmapEx aBitmapExBW( aBitmapBW, aBitmapBW );
@@ -137,12 +150,14 @@ void setupMethodStubs( functor_vector_type& res )
aMtf.AddAction( new MetaFillColorAction(Color(COL_RED),true) );
aMtf.AddAction( new MetaRectAction(aRect) );
+#ifdef FIXME_NEEDS_LOVE
add(res,
"DrawTextArray",
boost::bind(
&OutputDevice::DrawTextArray,
_1,
aPt1, aString, (const sal_Int32*)0, (sal_uInt16)0, aString.getLength() ));
+#endif
/* void DrawPixel( const Point& rPt, const Color& rColor ); */
add(res,
@@ -283,6 +298,7 @@ void setupMethodStubs( functor_vector_type& res )
aRect2.TopLeft(), aRect2.GetSize(),
aRect.TopLeft(), aRect.GetSize()));
+#ifdef FIXME_VDEV
/* void DrawOutDev( const Point& rDestPt, const Size& rDestSize,
const Point& rSrcPt, const Size& rSrcSize,
const OutputDevice& rOutDev );
@@ -314,6 +330,7 @@ void setupMethodStubs( functor_vector_type& res )
aRect2.TopLeft(), aRect2.GetSize(),
aRect.TopLeft(), aRect.GetSize(),
boost::cref(aVDev) ));
+#endif
/* void CopyArea( const Point& rDestPt,
const Point& rSrcPt, const Size& rSrcSize,
@@ -326,6 +343,7 @@ void setupMethodStubs( functor_vector_type& res )
_1,
aPt1,aPt3,aRect2.GetSize(),(sal_uInt16)0 ));
+#ifdef NEEDS_QUALIY_PARAMTER
/* void DrawBitmap( const Point& rDestPt,
const Bitmap& rBitmap );
*/
@@ -376,6 +394,7 @@ void setupMethodStubs( functor_vector_type& res )
_1,
aPt1,aRect.GetSize(),aBitmap ));
+#if 0
/* void DrawBitmap( const Point& rDestPt, const Size& rDestSize,
const Point& rSrcPtPixel, const Size& rSrcSizePixel,
const Bitmap& rBitmap );
@@ -391,6 +410,7 @@ void setupMethodStubs( functor_vector_type& res )
&OutputDevice::DrawBitmap),
_1,
aPt1,aRect.GetSize(),aPt3,aRect2.GetSize(),aBitmapAlien ));
+#endif
/* void DrawBitmap( const Point& rDestPt, const Size& rDestSize,
const Point& rSrcPtPixel, const Size& rSrcSizePixel,
@@ -687,6 +707,8 @@ void setupMethodStubs( functor_vector_type& res )
_1,
aPt1,aRect.GetSize(),aImage,(sal_uInt16)0 ));
+#endif // NEEDS_QUALITY_PARAMATER
+
/* void DrawGradient( const Rectangle& rRect, const Gradient& rGradient ); */
add(res,
"DrawGradient",
@@ -721,6 +743,7 @@ void setupMethodStubs( functor_vector_type& res )
_1,
aRect2,aWallpaper ));
+#ifdef FIXME_HAVE_WAVE_NORMAL
/* void DrawWaveLine( const Point& rStartPos, const Point& rEndPos, sal_uInt16 nStyle ); */
add(res,
"DrawWaveLine",
@@ -728,6 +751,7 @@ void setupMethodStubs( functor_vector_type& res )
&OutputDevice::DrawWaveLine,
_1,
aPt1,aPt2,(sal_uInt16)WAVE_NORMAL ));
+#endif
/* void DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags ); */
add(res,
@@ -783,7 +807,7 @@ void grindFunc( OutputDevice& rTarget,
iter->second(&rTarget);
if( rTarget.GetOutDevType() == OUTDEV_WINDOW )
- static_cast<Window&>(rTarget).Sync();
+ static_cast< vcl::Window & >( rTarget ).Sync();
fprintf( stdout,
"Duration: %d ms (%d repetitions)\tOperation: %s\tSetup: %s\n",
@@ -824,13 +848,13 @@ void outDevGrind( OutputDevice& rTarget, sal_Int32 nTurns=100 )
rTarget.SetLineColor( Color(COL_BLACK) );
rTarget.SetFillColor( Color(COL_GREEN) );
rTarget.SetRasterOp( ROP_OVERPAINT );
- rTarget.SetClipRegion( aClipRect );
+ rTarget.SetClipRegion( vcl::Region( aClipRect ) );
grindFunc( rTarget, iter, nTurns, "with rect clip, w/o xor" );
rTarget.SetLineColor( Color(COL_BLACK) );
rTarget.SetFillColor( Color(COL_GREEN) );
rTarget.SetRasterOp( ROP_OVERPAINT );
- rTarget.SetClipRegion( aClipPoly );
+ rTarget.SetClipRegion( vcl::Region( aClipPoly ) );
grindFunc( rTarget, iter, nTurns, "with complex clip, w/o xor" );
rTarget.SetLineColor( Color(COL_BLACK) );
@@ -842,13 +866,13 @@ void outDevGrind( OutputDevice& rTarget, sal_Int32 nTurns=100 )
rTarget.SetLineColor( Color(COL_BLACK) );
rTarget.SetFillColor( Color(COL_GREEN) );
rTarget.SetRasterOp( ROP_XOR );
- rTarget.SetClipRegion( aClipRect );
+ rTarget.SetClipRegion( vcl::Region( aClipRect ) );
grindFunc( rTarget, iter, nTurns, "with rect clip, with xor" );
rTarget.SetLineColor( Color(COL_BLACK) );
rTarget.SetFillColor( Color(COL_GREEN) );
rTarget.SetRasterOp( ROP_XOR );
- rTarget.SetClipRegion( aClipPoly );
+ rTarget.SetClipRegion( vcl::Region( aClipPoly ) );
grindFunc( rTarget, iter, nTurns, "with complex clip, with xor" );
++iter;
@@ -874,11 +898,21 @@ sal_uInt16 GrindApp::Exception( sal_uInt16 nError )
int GrindApp::Main()
{
+ TestWindow aWindow;
+ aWindow.Execute();
+ return 0;
+}
+
+} // namespace
+
+
+SAL_IMPLEMENT_MAIN()
+{
bool bHelp = false;
- for( sal_uInt16 i = 0; i < GetCommandLineParamCount(); i++ )
+ for( sal_uInt16 i = 0; i < Application::GetCommandLineParamCount(); i++ )
{
- OUString aParam = GetCommandLineParam( i );
+ OUString aParam = Application::GetCommandLineParam( i );
if( aParam == "--help" || aParam == "-h" )
bHelp = true;
@@ -890,35 +924,24 @@ int GrindApp::Main()
return EXIT_SUCCESS;
}
- // create the global service-manager
- uno::Reference< lang::XMultiServiceFactory > xFactory;
- try
- {
- uno::Reference< uno::XComponentContext > xCtx = ::cppu::defaultBootstrap_InitialComponentContext();
- xFactory = uno::Reference< lang::XMultiServiceFactory >( xCtx->getServiceManager(),
- uno::UNO_QUERY );
- if( xFactory.is() )
- ::comphelper::setProcessServiceFactory( xFactory );
- }
- catch( uno::Exception& )
- {
- }
+ tools::extendApplicationEnvironment();
- if( !xFactory.is() )
- {
- fprintf( stderr,
- "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" );
- exit( 1 );
- }
+ uno::Reference< uno::XComponentContext > xContext = cppu::defaultBootstrap_InitialComponentContext();
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), uno::UNO_QUERY );
- TestWindow pWindow;
- pWindow.Execute();
+ if( !xServiceManager.is() )
+ Application::Abort( "Failed to bootstrap" );
- return EXIT_SUCCESS;
-}
+ comphelper::setProcessServiceFactory( xServiceManager );
-} // namespace
+ InitVCL();
+
+ GrindApp aGrindApp;
+ aGrindApp.Main();
-GrindApp aGrindApp;
+ DeInitVCL();
+
+ return EXIT_SUCCESS;
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 7fe1b2d09fb7..daa877f95385 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -5,152 +5,362 @@
* 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/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <sal/main.h>
-#include <tools/extendapplicationenvironment.hxx>
-
-#include <cppuhelper/bootstrap.hxx>
+#include <rtl/bootstrap.hxx>
#include <comphelper/processfactory.hxx>
-
+#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/ucb/UniversalContentBroker.hpp>
+
+#include <vcl/vclmain.hxx>
-#include <vcl/event.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
#include <vcl/svapp.hxx>
+#include <vcl/pngread.hxx>
#include <vcl/wrkwin.hxx>
-#include <vcl/msgbox.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/graphicfilter.hxx>
-#include <unistd.h>
-#include <stdio.h>
+# define FIXME_ALPHA_WORKING
+# define FIXME_ROUNDED_RECT_WORKING
+# define FIXME_DRAW_TRANSPARENT_WORKING
+#if 0
+#endif
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::lang;
-using namespace cppu;
+using namespace css;
-// Forward declaration
-void Main();
+class DemoBase :
+ public WorkWindow // hide OutputDevice if necessary
+{
+public:
+ DemoBase() : WorkWindow( NULL, WB_APP | WB_STDWORK)
+ {
+ }
+ OutputDevice &getOutDev() { return *this; }
+};
-SAL_IMPLEMENT_MAIN()
+class DemoWin : public DemoBase
{
- try
+ Bitmap maIntroBW;
+ BitmapEx maIntro;
+
+public:
+ DemoWin() : DemoBase()
+ {
+ // Needed to find images
+ OUString aPath;
+ rtl::Bootstrap::get("SYSBINDIR", aPath);
+#ifdef FIXME_THIS_FAILS
+ rtl::Bootstrap::set("BRAND_BASE_DIR", aPath + "/..");
+ if (Application::LoadBrandBitmap("intro", maIntro))
+ Application::Abort("Failed to load intro image");
+#else
+ aPath = aPath + "/intro.png";
+ SvFileStream aFileStream( aPath, STREAM_READ );
+ GraphicFilter aGraphicFilter(false);
+ Graphic aGraphic;
+ if (aGraphicFilter.ImportGraphic(aGraphic, aPath, aFileStream) != 0)
+ Application::Abort("Failed to load intro image: " + aPath);
+ maIntro = aGraphic.GetBitmapEx();
+#endif
+ maIntroBW = maIntro.GetBitmap();
+ maIntroBW.Filter( BMP_FILTER_EMBOSS_GREY );
+ }
+
+ void drawToDevice(OutputDevice &r, bool bVdev);
+
+ virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE
+ {
+ fprintf(stderr, "DemoWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight());
+ drawToDevice(getOutDev(), false);
+ }
+
+ std::vector<Rectangle> partitionAndClear(OutputDevice &rDev,
+ int nX, int nY);
+
+ void drawBackground(OutputDevice &rDev)
+ {
+ Rectangle r(Point(0,0), rDev.GetOutputSizePixel());
+ Gradient aGradient;
+ aGradient.SetStartColor(COL_BLUE);
+ aGradient.SetEndColor(COL_GREEN);
+ aGradient.SetStyle(GradientStyle_LINEAR);
+// aGradient.SetBorder(r.GetSize().Width()/20);
+ rDev.DrawGradient(r, aGradient);
+ }
+
+ void drawRadialLines(OutputDevice &rDev, Rectangle r)
{
- tools::extendApplicationEnvironment();
+ rDev.SetFillColor(Color(COL_LIGHTRED));
+ rDev.SetLineColor(Color(COL_BLACK));
+ rDev.DrawRect( r );
- Reference< XComponentContext > xContext = defaultBootstrap_InitialComponentContext();
- Reference< XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), UNO_QUERY );
+ // FIXME: notice these appear reflected at the bottom not the top.
+ for(int i=0; i<r.GetHeight(); i+=15)
+ rDev.DrawLine( Point(r.Left(), r.Top()+i), Point(r.Right(), r.Bottom()-i) );
+ for(int i=0; i<r.GetWidth(); i+=15)
+ rDev.DrawLine( Point(r.Left()+i, r.Bottom()), Point(r.Right()-i, r.Top()) );
- if( !xServiceManager.is() )
- Application::Abort( "Failed to bootstrap" );
+ // Should draw a white-line across the middle
+ Color aLastPixel( COL_WHITE );
+ Point aCenter((r.Left() + r.Right())/2 - 4,
+ (r.Top() + r.Bottom())/2 - 4);
+ for(int i=0; i<8; i++)
+ {
+ rDev.DrawPixel(aCenter, aLastPixel);
+ aLastPixel = rDev.GetPixel(aCenter);
+ aCenter.Move(1,1);
+ }
+ }
- comphelper::setProcessServiceFactory( xServiceManager );
+ void drawText(OutputDevice &rDev, Rectangle r)
- InitVCL();
- ::Main();
- DeInitVCL();
+ {
+ rDev.SetTextColor( Color( COL_BLACK ) );
+ vcl::Font aFont( OUString( "Times" ), Size( 0, 25 ) );
+ rDev.SetFont( aFont );
+ rDev.DrawText( r, OUString( "Just a simple text" ) );
}
- catch (const Exception& e)
+
+ void drawPoly(OutputDevice &rDev, Rectangle r)
+ // pretty
{
- SAL_WARN("vcl.app", "Fatal exception: " << e.Message);
- return 1;
+ drawCheckered(rDev, r);
+
+ long nDx = r.GetWidth()/20;
+ long nDy = r.GetHeight()/20;
+ Rectangle aShrunk(r);
+ aShrunk.Move(nDx, nDy);
+ aShrunk.SetSize(Size(r.GetWidth()-nDx*2,
+ r.GetHeight()-nDy*2));
+ Polygon aPoly(aShrunk);
+ tools::PolyPolygon aPPoly(aPoly);
+ rDev.SetLineColor(Color(COL_RED));
+ rDev.SetFillColor(Color(COL_RED));
+ // This hits the optional 'drawPolyPolygon' code-path
+ rDev.DrawTransparent(aPPoly, 64);
}
+ void drawEllipse(OutputDevice &rDev, Rectangle r)
- return 0;
-}
+ {
+ rDev.SetLineColor(Color(COL_RED));
+ rDev.SetFillColor(Color(COL_GREEN));
+ rDev.DrawEllipse(r);
+ }
+ void drawCheckered(OutputDevice &rDev, Rectangle r)
-class MyWin : public WorkWindow
-{
-public:
- MyWin( vcl::Window* pParent, WinBits nWinStyle );
-
- virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
- virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
- virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
- virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
- virtual void KeyUp( const KeyEvent& rKEvt ) SAL_OVERRIDE;
- virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
- virtual void Resize() SAL_OVERRIDE;
+ {
+ rDev.DrawCheckered(r.TopLeft(), r.GetSize());
+ }
+ void drawGradient(OutputDevice &rDev, Rectangle r)
+
+ {
+ Gradient aGradient;
+ aGradient.SetStartColor(COL_YELLOW);
+ aGradient.SetEndColor(COL_RED);
+// aGradient.SetAngle(45);
+ aGradient.SetStyle(GradientStyle_RECT);
+ aGradient.SetBorder(r.GetSize().Width()/20);
+ rDev.DrawGradient(r, aGradient);
+ }
+ void drawBitmap(OutputDevice &rDev, Rectangle r)
+
+ {
+ Bitmap aBitmap(maIntroBW);
+ aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY);
+ rDev.DrawBitmap(r.TopLeft(), aBitmap);
+ }
+ void drawBitmapEx(OutputDevice &rDev, Rectangle r)
+
+ {
+ drawCheckered(rDev, r);
+
+ BitmapEx aBitmap(maIntro);
+ aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY);
+#ifdef FIXME_ALPHA_WORKING
+ AlphaMask aSemiTransp(aBitmap.GetSizePixel());
+ aSemiTransp.Erase(64);
+ rDev.DrawBitmapEx(r.TopLeft(), BitmapEx(aBitmap.GetBitmap(),
+ aSemiTransp));
+#else
+ rDev.DrawBitmapEx(r.TopLeft(), aBitmap);
+#endif
+ }
+ void drawPolyPolgons(OutputDevice &rDev, Rectangle r)
+
+ {
+ struct {
+ double nX, nY;
+ } aPoints[] = { { 0.1, 0.1 }, { 0.9, 0.9 },
+ { 0.9, 0.1 }, { 0.1, 0.9 },
+ { 0.1, 0.1 } };
+
+ tools::PolyPolygon aPolyPoly;
+ // Render 4x polygons & aggregate into another PolyPolygon
+ for (int x = 0; x < 2; x++)
+ {
+ for (int y = 0; y < 2; y++)
+ {
+ Rectangle aSubRect(r);
+ aSubRect.Move(x * r.GetWidth()/3, y * r.GetHeight()/3);
+ aSubRect.SetSize(Size(r.GetWidth()/2, r.GetHeight()/4));
+ Polygon aPoly(SAL_N_ELEMENTS(aPoints));
+ for (size_t v = 0; v < SAL_N_ELEMENTS(aPoints); v++)
+ {
+ aPoly.SetPoint(Point(aSubRect.Left() +
+ aSubRect.GetWidth() * aPoints[v].nX,
+ aSubRect.Top() +
+ aSubRect.GetHeight() * aPoints[v].nY),
+ v);
+ }
+ rDev.SetLineColor(Color(COL_YELLOW));
+ rDev.SetFillColor(Color(COL_BLACK));
+ rDev.DrawPolygon(aPoly);
+
+ // now move and add to the polypolygon
+ aPoly.Move(0, r.GetHeight()/2);
+ aPolyPoly.Insert(aPoly);
+ }
+ }
+ rDev.SetLineColor(Color(COL_LIGHTRED));
+ rDev.SetFillColor(Color(COL_GREEN));
+#ifdef FIXME_DRAW_TRANSPARENT_WORKING
+ rDev.DrawTransparent(aPolyPoly, 50);
+#else
+ rDev.DrawPolyPolygon(aPolyPoly);
+#endif
+ }
+ void drawToVirtualDevice(OutputDevice &rDev, Rectangle r)
+ {
+ VirtualDevice aNested;
+ aNested.SetOutputSize(r.GetSize());
+ Rectangle aWhole(Point(0,0), r.GetSize());
+ // mini me
+ drawToDevice(aNested, true);
+
+ Bitmap aBitmap(aNested.GetBitmap(Point(0,0),aWhole.GetSize()));
+ rDev.DrawBitmap(r.TopLeft(), aBitmap);
+ }
+
+ void fetchDrawBitmap(OutputDevice &rDev, Rectangle r)
+ {
+ // FIXME: should work ...
+ Bitmap aBitmap(GetBitmap(Point(0,0),rDev.GetOutputSizePixel()));
+ aBitmap.Scale(r.GetSize(), BMP_SCALE_BESTQUALITY);
+ rDev.DrawBitmap(r.TopLeft(), aBitmap);
+ }
};
-void Main()
+std::vector<Rectangle> DemoWin::partitionAndClear(OutputDevice &rDev, int nX, int nY)
{
- MyWin aMainWin( NULL, WB_APP | WB_STDWORK );
- aMainWin.SetText( OUString( "VCLDemo - VCL Workbench" ) );
- aMainWin.Show();
+ Rectangle r;
+ std::vector<Rectangle> aRegions;
- Application::Execute();
-}
+ // Make small cleared area for these guys
+ Size aSize(rDev.GetOutputSizePixel());
+ long nBorderSize = aSize.Width() / 32;
+ long nBoxWidth = (aSize.Width() - nBorderSize*(nX+1)) / nX;
+ long nBoxHeight = (aSize.Height() - nBorderSize*(nY+1)) / nY;
+ for (int y = 0; y < nY; y++ )
+ {
+ for (int x = 0; x < nX; x++ )
+ {
+ r.SetPos(Point(nBorderSize + (nBorderSize + nBoxWidth) * x,
+ nBorderSize + (nBorderSize + nBoxHeight) * y));
+ r.SetSize(Size(nBoxWidth, nBoxHeight));
-MyWin::MyWin( vcl::Window* pParent, WinBits nWinStyle ) :
- WorkWindow( pParent, nWinStyle )
-{
-}
+ // knock up a nice little border
+ rDev.SetLineColor(COL_GRAY);
+ rDev.SetFillColor(COL_LIGHTGRAY);
+ if ((x + y) % 2)
+ rDev.DrawRect(r);
+ else
+ {
+#ifdef FIXME_ROUNDED_RECT_WORKING
+ rDev.DrawRect(r, nBorderSize, nBorderSize);
+#else
+ rDev.DrawRect(r);
+#endif
+ }
-void MyWin::MouseMove( const MouseEvent& rMEvt )
-{
- WorkWindow::MouseMove( rMEvt );
-}
+ aRegions.push_back(r);
+ }
+ }
-void MyWin::MouseButtonDown( const MouseEvent& rMEvt )
-{
- Rectangle aRect(0,0,4,4);
- aRect.SetPos( rMEvt.GetPosPixel() );
- SetFillColor(Color(COL_RED));
- DrawRect( aRect );
+ return aRegions;
}
-void MyWin::MouseButtonUp( const MouseEvent& rMEvt )
+void DemoWin::drawToDevice(OutputDevice &rDev, bool bVdev)
{
- WorkWindow::MouseButtonUp( rMEvt );
-}
+ drawBackground(rDev);
-void MyWin::KeyInput( const KeyEvent& rKEvt )
-{
- WorkWindow::KeyInput( rKEvt );
-}
+ std::vector<Rectangle> aRegions(partitionAndClear(rDev, 4, 3));
-void MyWin::KeyUp( const KeyEvent& rKEvt )
-{
- WorkWindow::KeyUp( rKEvt );
+ drawRadialLines(rDev, aRegions[0]);
+ drawText(rDev, aRegions[1]);
+ drawPoly(rDev, aRegions[2]);
+ drawEllipse(rDev, aRegions[3]);
+ drawCheckered(rDev, aRegions[4]);
+ drawBitmapEx(rDev, aRegions[5]);
+ drawBitmap(rDev, aRegions[6]);
+ drawGradient(rDev, aRegions[7]);
+ drawPolyPolgons(rDev, aRegions[8]);
+ if (!bVdev)
+ drawToVirtualDevice(rDev, aRegions[9]);
+ // last - thumbnail all the above
+ fetchDrawBitmap(rDev, aRegions[10]);
}
-void MyWin::Paint( const Rectangle& rRect )
+class DemoApp : public Application
{
- fprintf(stderr, "MyWin::Paint(%ld,%ld,%ld,%ld)\n", rRect.getX(), rRect.getY(), rRect.getWidth(), rRect.getHeight());
-
- Size aSz(GetSizePixel());
- Point aPt;
- Rectangle r(aPt, aSz);
-
- SetFillColor(Color(COL_BLUE));
- SetLineColor(Color(COL_YELLOW));
+public:
+ DemoApp() {}
- DrawRect( r );
+ virtual int Main() SAL_OVERRIDE
+ {
+ DemoWin aMainWin;
+ aMainWin.SetText( "Interactive VCL demo" );
+ aMainWin.Show();
+ Application::Execute();
+ return 0;
+ }
- for(int i=0; i<aSz.Height(); i+=15)
- DrawLine( Point(r.Left(), r.Top()+i), Point(r.Right(), r.Bottom()-i) );
- for(int i=0; i<aSz.Width(); i+=15)
- DrawLine( Point(r.Left()+i, r.Bottom()), Point(r.Right()-i, r.Top()) );
+protected:
+ uno::Reference<lang::XMultiServiceFactory> xMSF;
+ void Init() SAL_OVERRIDE
+ {
+ try
+ {
+ uno::Reference<uno::XComponentContext> xComponentContext
+ = ::cppu::defaultBootstrap_InitialComponentContext();
+ xMSF = uno::Reference<lang::XMultiServiceFactory>
+ ( xComponentContext->getServiceManager(), uno::UNO_QUERY );
+ if( !xMSF.is() )
+ Application::Abort("Bootstrap failure - no service manager");
- SetTextColor( Color( COL_WHITE ) );
- vcl::Font aFont( OUString( "Times" ), Size( 0, 25 ) );
- SetFont( aFont );
- DrawText( Point( 20, 30 ), OUString( "Just a simple test text" ) );
-}
+ ::comphelper::setProcessServiceFactory( xMSF );
+ }
+ catch (const uno::Exception &e)
+ {
+ Application::Abort("Bootstrap exception " + e.Message);
+ }
+ }
+ void DeInit() SAL_OVERRIDE
+ {
+ uno::Reference< lang::XComponent >(
+ comphelper::getProcessComponentContext(),
+ uno::UNO_QUERY_THROW )-> dispose();
+ ::comphelper::setProcessServiceFactory( NULL );
+ }
+};
-void MyWin::Resize()
+void vclmain::createApplication()
{
- WorkWindow::Resize();
+ static DemoApp aApp;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */