LibreOffice Module canvas (master)  1
cairo_devicehelper.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 
25 #include <tools/stream.hxx>
26 #include <vcl/bitmapex.hxx>
27 #include <vcl/canvastools.hxx>
28 #include <vcl/dibtools.hxx>
29 
30 #include <canvas/canvastools.hxx>
31 
32 #include "cairo_canvasbitmap.hxx"
33 #include "cairo_devicehelper.hxx"
34 
35 using namespace ::cairo;
36 using namespace ::com::sun::star;
37 
38 namespace cairocanvas
39 {
41  mpSurfaceProvider( nullptr ),
42  mpRefDevice( nullptr ),
43  mpSurface()
44  {
45  }
46 
47  void DeviceHelper::implInit( SurfaceProvider& rSurfaceProvider,
48  OutputDevice& rRefDevice )
49  {
50  mpSurfaceProvider = &rSurfaceProvider;
51  mpRefDevice = &rRefDevice;
52 
53  // no own surface, this is handled by derived classes
54  }
55 
56  void DeviceHelper::init( SurfaceProvider& rSurfaceProvider,
57  OutputDevice& rRefDevice )
58  {
59  implInit(rSurfaceProvider, rRefDevice);
60 
61  OutputDevice* pOutDev = getOutputDevice();
62  mpSurface = pOutDev->CreateSurface(pOutDev->GetOutOffXPixel(),
63  pOutDev->GetOutOffYPixel(),
64  pOutDev->GetOutputWidthPixel(),
65  pOutDev->GetOutputHeightPixel());
66  }
67 
69  {
70  // release all references
71  mpSurface.reset();
72  mpRefDevice = nullptr;
73  mpSurfaceProvider = nullptr;
74  }
75 
76  void DeviceHelper::setSize( const ::basegfx::B2ISize& rSize )
77  {
78  SAL_INFO(
79  "canvas.cairo",
80  "device size " << rSize.getX() << " x " << rSize.getY());
81 
82  if( !mpRefDevice )
83  return; // disposed
84 
85  OutputDevice* pOutDev = getOutputDevice();
86 
87  // X11 only
88  bool bReuseSurface = mpSurface &&
89  mpSurface->Resize(rSize.getX() + pOutDev->GetOutOffXPixel(),
90  rSize.getY() + pOutDev->GetOutOffYPixel());
91 
92  if (!bReuseSurface)
93  {
94  mpSurface = pOutDev->CreateSurface(
95  pOutDev->GetOutOffXPixel(),
96  pOutDev->GetOutOffYPixel(),
97  rSize.getX(), rSize.getY() );
98  }
99  }
100 
101  geometry::RealSize2D DeviceHelper::getPhysicalResolution()
102  {
103  // Map a one-by-one millimeter box to pixel
104  const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
105  mpRefDevice->SetMapMode( MapMode(MapUnit::MapMM) );
106  const Size aPixelSize( mpRefDevice->LogicToPixel(Size(1,1)) );
107  mpRefDevice->SetMapMode( aOldMapMode );
108 
109  return vcl::unotools::size2DFromSize( aPixelSize );
110  }
111 
112  geometry::RealSize2D DeviceHelper::getPhysicalSize()
113  {
114  if( !mpRefDevice )
116 
117  // Map the pixel dimensions of the output window to millimeter
118  const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
119  mpRefDevice->SetMapMode( MapMode(MapUnit::MapMM) );
121  mpRefDevice->SetMapMode( aOldMapMode );
122 
123  return vcl::unotools::size2DFromSize( aLogSize );
124  }
125 
126  uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon(
127  const uno::Reference< rendering::XGraphicDevice >& ,
128  const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
129  {
130  // disposed?
131  if( !mpSurfaceProvider )
132  return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed
133 
134  return uno::Reference< rendering::XLinePolyPolygon2D >(
135  new ::basegfx::unotools::UnoPolyPolygon(
137  }
138 
139  uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon(
140  const uno::Reference< rendering::XGraphicDevice >& ,
141  const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& points )
142  {
143  // disposed?
144  if( !mpSurfaceProvider )
145  return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed
146 
147  return uno::Reference< rendering::XBezierPolyPolygon2D >(
148  new ::basegfx::unotools::UnoPolyPolygon(
150  }
151 
152  uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap(
153  const uno::Reference< rendering::XGraphicDevice >& rDevice,
154  const geometry::IntegerSize2D& size )
155  {
156  // disposed?
157  if( !mpSurfaceProvider )
158  return uno::Reference< rendering::XBitmap >(); // we're disposed
159 
160  return uno::Reference< rendering::XBitmap >(
161  new CanvasBitmap(
164  rDevice.get(),
165  false ));
166  }
167 
168  uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap(
169  const uno::Reference< rendering::XGraphicDevice >& ,
170  const geometry::IntegerSize2D& /*size*/ )
171  {
172  return uno::Reference< rendering::XVolatileBitmap >();
173  }
174 
175  uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap(
176  const uno::Reference< rendering::XGraphicDevice >& rDevice,
177  const geometry::IntegerSize2D& size )
178  {
179  // disposed?
180  if( !mpSurfaceProvider )
181  return uno::Reference< rendering::XBitmap >(); // we're disposed
182 
183  return uno::Reference< rendering::XBitmap >(
184  new CanvasBitmap(
187  rDevice.get(),
188  true ));
189  }
190 
191  uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap(
192  const uno::Reference< rendering::XGraphicDevice >& ,
193  const geometry::IntegerSize2D& /*size*/ )
194  {
195  return uno::Reference< rendering::XVolatileBitmap >();
196  }
197 
199  {
200  return css::uno::Any(false);
201  }
202 
204  {
205  return uno::Any( reinterpret_cast< sal_Int64 >(mpRefDevice.get()) );
206  }
207 
209  {
210  return uno::Any();
211  }
212 
213  namespace
214  {
215  struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
216  DeviceColorSpace>
217  {
218  uno::Reference<rendering::XColorSpace> operator()()
219  {
221  }
222  };
223  }
224 
225  uno::Reference<rendering::XColorSpace> const & DeviceHelper::getColorSpace() const
226  {
227  // always the same
228  return DeviceColorSpace::get();
229  }
230 
232  {
233  static sal_Int32 nFilePostfixCount(0);
234 
235  if( !mpRefDevice )
236  return;
237 
238  OUString aFilename = "dbg_frontbuffer" + OUString::number(nFilePostfixCount) + ".bmp";
239 
240  SvFileStream aStream( aFilename, StreamMode::STD_READWRITE );
241 
242  const ::Point aEmptyPoint;
243  bool bOldMap( mpRefDevice->IsMapModeEnabled() );
244  mpRefDevice->EnableMapMode( false );
245  const ::BitmapEx aTempBitmap(mpRefDevice->GetBitmapEx(aEmptyPoint, mpRefDevice->GetOutputSizePixel()));
246  WriteDIB(aTempBitmap, aStream, false);
247  mpRefDevice->EnableMapMode( bOldMap );
248 
249  ++nFilePostfixCount;
250  }
251 
252  SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, int aContent )
253  {
254  if( mpSurface )
255  return mpSurface->getSimilar( aContent, rSize.getX(), rSize.getY() );
256 
257  return SurfaceSharedPtr();
258  }
259 
261  {
262  if (mpRefDevice)
263  return mpRefDevice->CreateBitmapSurface(rData, rSize);
264 
265  return SurfaceSharedPtr();
266  }
267 }
268 
269 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Target interface for XCachedPrimitive implementations.
bool IsMapModeEnabled() const
css::uno::Reference< css::rendering::XVolatileBitmap > createVolatileAlphaBitmap(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::geometry::IntegerSize2D &size)
tools::Long GetOutOffXPixel() const
cairo::SurfaceSharedPtr CreateSurface(const cairo::CairoSurfaceSharedPtr &rSurface) const
css::uno::Any getSurfaceHandle() const
const MapMode & GetMapMode() const
css::uno::Reference< css::rendering::XLinePolyPolygon2D > createCompatibleLinePolyPolygon(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::uno::Sequence< css::uno::Sequence< css::geometry::RealPoint2D > > &points)
cairo::SurfaceSharedPtr CreateBitmapSurface(const BitmapSystemData &rData, const Size &rSize) const
void disposing()
Dispose all internal references.
void EnableMapMode(bool bEnable=true)
void SetMapMode()
::basegfx::B2DPolyPolygon polyPolygonFromPoint2DSequenceSequence(const uno::Sequence< uno::Sequence< geometry::RealPoint2D > > &points)
css::uno::Reference< css::rendering::XVolatileBitmap > createVolatileBitmap(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::geometry::IntegerSize2D &size)
::basegfx::B2DPolyPolygon polyPolygonFromBezier2DSequenceSequence(const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > > &curves)
void init(SurfaceProvider &rSurfaceProvider, OutputDevice &rRefDevice)
init helper
std::shared_ptr< Surface > SurfaceSharedPtr
css::geometry::RealSize2D getPhysicalResolution()
void setSize(const ::basegfx::B2ISize &rSize)
css::uno::Reference< css::rendering::XBitmap > createCompatibleAlphaBitmap(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::geometry::IntegerSize2D &size)
tools::Long GetOutputHeightPixel() const
geometry::RealSize2D size2DFromSize(const Size &rSize)
css::uno::Any isAccelerated() const
Size GetOutputSizePixel() const
css::uno::Any getDeviceHandle() const
VclPtr< OutputDevice > mpRefDevice
tools::Long GetOutOffYPixel() const
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
::cairo::SurfaceSharedPtr createSurface(const ::basegfx::B2ISize &rSize, int aContent)
void implInit(SurfaceProvider &rSurfaceProvider, OutputDevice &rRefDevice)
init helper
::cairo::SurfaceSharedPtr mpSurface
SurfaceProvider * mpSurfaceProvider
Surface provider.
uno::Reference< rendering::XColorSpace > createStandardColorSpace()
css::geometry::RealSize2D getPhysicalSize()
::basegfx::B2IVector b2ISizeFromIntegerSize2D(const geometry::IntegerSize2D &rSize)
geometry::RealSize2D createInfiniteSize2D()
Create a RealSize2D with both coordinate values set to +infinity.
Definition: canvastools.cxx:68
#define SAL_INFO(area, stream)
css::uno::Reference< css::rendering::XBitmap > createCompatibleBitmap(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::geometry::IntegerSize2D &size)
::rtl::Reference< SurfaceProvider > SurfaceProviderRef
css::uno::Reference< css::rendering::XBezierPolyPolygon2D > createCompatibleBezierPolyPolygon(const css::uno::Reference< css::rendering::XGraphicDevice > &rDevice, const css::uno::Sequence< css::uno::Sequence< css::geometry::RealBezierSegment2D > > &points)
css::uno::Reference< css::rendering::XColorSpace > const & getColorSpace() const
BitmapEx GetBitmapEx(const Point &rSrcPt, const Size &rSize) const
OutputDevice * get() const
void dumpScreenContent() const
called when DumpScreenContent property is enabled on XGraphicDevice, and writes out bitmaps of curren...
OutputDevice * getOutputDevice() const
bool WriteDIB(const Bitmap &rSource, SvStream &rOStm, bool bCompressed, bool bFileHeader)
tools::Long GetOutputWidthPixel() const
COMReference< surface_type > mpSurface