LibreOffice Module canvas (master)  1
impltools.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 
29 #include <rtl/math.hxx>
30 #include <tools/diagnose_ex.h>
31 #include <sal/log.hxx>
32 #include <vcl/bitmapex.hxx>
33 #include <vcl/canvastools.hxx>
34 #include <vcl/BitmapTools.hxx>
35 #include <vcl/metric.hxx>
36 #include <vcl/skia/SkiaHelper.hxx>
37 
38 #include <canvas/canvastools.hxx>
39 
40 #include "canvasbitmap.hxx"
41 #include "impltools.hxx"
42 #include "spritecanvas.hxx"
43 
44 
45 using namespace ::com::sun::star;
46 
48 {
49  ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XBitmap >& xBitmap )
50  {
51  // TODO(F3): CanvasCustomSprite should also be tunnelled
52  // through (also implements XIntegerBitmap interface)
53  CanvasBitmap* pBitmapImpl = dynamic_cast< CanvasBitmap* >( xBitmap.get() );
54 
55  if( pBitmapImpl )
56  {
57  return pBitmapImpl->getBitmap();
58  }
59  else
60  {
61  SpriteCanvas* pCanvasImpl = dynamic_cast< SpriteCanvas* >( xBitmap.get() );
62  if( pCanvasImpl && pCanvasImpl->getBackBuffer() )
63  {
64  // TODO(F3): mind the plain Canvas impl. Consolidate with CWS canvas05
65  const ::OutputDevice& rDev( pCanvasImpl->getBackBuffer()->getOutDev() );
66  const ::Point aEmptyPoint;
67  return rDev.GetBitmapEx( aEmptyPoint,
68  rDev.GetOutputSizePixel() );
69  }
70 
71  // TODO(F2): add support for floating point bitmap formats
72  uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntBmp(
73  xBitmap, uno::UNO_QUERY_THROW );
74 
76  if( !!aBmpEx )
77  return aBmpEx;
78 
79  // TODO(F1): extract pixel from XBitmap interface
80  ENSURE_OR_THROW( false,
81  "bitmapExFromXBitmap(): could not extract bitmap" );
82  }
83 
84  return ::BitmapEx();
85  }
86 
87  bool setupFontTransform( ::Point& o_rPoint,
88  vcl::Font& io_rVCLFont,
89  const rendering::ViewState& rViewState,
90  const rendering::RenderState& rRenderState,
91  ::OutputDevice const & rOutDev )
92  {
94 
96  rViewState,
97  rRenderState);
98 
99  ::basegfx::B2DTuple aScale;
100  ::basegfx::B2DTuple aTranslate;
101  double nRotate, nShearX;
102 
103  aMatrix.decompose( aScale, aTranslate, nRotate, nShearX );
104 
105  // query font metric _before_ tampering with width and height
106  if( !::rtl::math::approxEqual(aScale.getX(), aScale.getY()) )
107  {
108  // retrieve true font width
109  const sal_Int32 nFontWidth( rOutDev.GetFontMetric( io_rVCLFont ).GetAverageFontWidth() );
110 
111  const sal_Int32 nScaledFontWidth( ::basegfx::fround(nFontWidth * aScale.getX()) );
112 
113  if( !nScaledFontWidth )
114  {
115  // scale is smaller than one pixel - disable text
116  // output altogether
117  return false;
118  }
119 
120  io_rVCLFont.SetAverageFontWidth( nScaledFontWidth );
121  }
122 
123  if( !::rtl::math::approxEqual(aScale.getY(), 1.0) )
124  {
125  const sal_Int32 nFontHeight( io_rVCLFont.GetFontHeight() );
126  io_rVCLFont.SetFontHeight( ::basegfx::fround(nFontHeight * aScale.getY()) );
127  }
128 
129  io_rVCLFont.SetOrientation( Degree10( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) ) );
130 
131  // TODO(F2): Missing functionality in VCL: shearing
132  o_rPoint.setX( ::basegfx::fround(aTranslate.getX()) );
133  o_rPoint.setY( ::basegfx::fround(aTranslate.getY()) );
134 
135  return true;
136  }
137 
138  bool isRectangle( const ::tools::PolyPolygon& rPolyPoly )
139  {
140  // exclude some cheap cases first
141  if( rPolyPoly.Count() != 1 )
142  return false;
143 
144  const ::tools::Polygon& rPoly( rPolyPoly[0] );
145 
146  sal_uInt16 nCount( rPoly.GetSize() );
147  if( nCount < 4 )
148  return false;
149 
150  // delegate to basegfx
151  return ::basegfx::utils::isRectangle( rPoly.getB2DPolygon() );
152  }
153 
154 
155  // VCL-Canvas related
156 
157 
158  ::Point mapRealPoint2D( const geometry::RealPoint2D& rPoint,
159  const rendering::ViewState& rViewState,
160  const rendering::RenderState& rRenderState )
161  {
163 
164  ::basegfx::B2DHomMatrix aMatrix;
166  rViewState,
167  rRenderState);
168 
169  return vcl::unotools::pointFromB2DPoint( aPoint );
170  }
171 
172  ::tools::PolyPolygon mapPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly,
173  const rendering::ViewState& rViewState,
174  const rendering::RenderState& rRenderState )
175  {
176  ::basegfx::B2DHomMatrix aMatrix;
178  rViewState,
179  rRenderState);
180 
181  ::basegfx::B2DPolyPolygon aTemp( rPoly );
182 
183  aTemp.transform( aMatrix );
184 
185  return ::tools::PolyPolygon( aTemp );
186  }
187 
189  const ::basegfx::B2DHomMatrix& rTransform )
190  {
191  SAL_INFO( "canvas.vcl", "::vclcanvas::tools::transformBitmap()" );
192  SAL_INFO( "canvas.vcl", "::vclcanvas::tools::transformBitmap: 0x" << std::hex << &rBitmap );
193 
194  // calc transformation and size of bitmap to be
195  // generated. Note, that the translational components are
196  // deleted from the transformation; this can be handled by
197  // an offset when painting the bitmap
198  const Size aBmpSize( rBitmap.GetSizePixel() );
199  ::basegfx::B2DRectangle aDestRect;
200 
201  // calc effective transformation for bitmap
202  const ::basegfx::B2DRectangle aSrcRect( 0, 0,
203  aBmpSize.Width(),
204  aBmpSize.Height() );
206  aSrcRect,
207  rTransform );
208 
209  // re-center bitmap, such that it's left, top border is
210  // aligned with (0,0). The method takes the given
211  // rectangle, and calculates a transformation that maps
212  // this rectangle unscaled to the origin.
213  ::basegfx::B2DHomMatrix aLocalTransform;
215  aSrcRect,
216  rTransform );
217 
218  return vcl::bitmap::CanvasTransformBitmap(rBitmap, rTransform, aDestRect, aLocalTransform);
219  }
220 
222  {
223 #if defined( MACOSX )
224  // use AA on VCLCanvas for Mac
225  pDevice->SetAntialiasing( AntialiasingFlags::Enable | pDevice->GetAntialiasing() );
226 #else
227  // switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
228  // is not required to do AA. It would need to be adapted to use it correctly
229  // (especially gradient painting). This will need extra work.
230  if( SkiaHelper::isVCLSkiaEnabled()) // But Skia handles AA fine.
231  pDevice->SetAntialiasing( AntialiasingFlags::Enable | pDevice->GetAntialiasing() );
232  else
233  pDevice->SetAntialiasing(pDevice->GetAntialiasing() & ~AntialiasingFlags::Enable);
234 #endif
235  }
236 
237 }
238 
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::Point mapRealPoint2D(const geometry::RealPoint2D &rPoint, const rendering::ViewState &rViewState, const rendering::RenderState &rRenderState)
Definition: impltools.cxx:158
void SetAntialiasing(AntialiasingFlags nMode)
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XBitmap > &xBitmap)
Definition: impltools.cxx:49
void SetAverageFontWidth(tools::Long nWidth)
::basegfx::B2DHomMatrix & mergeViewAndRenderTransform(::basegfx::B2DHomMatrix &combinedTransform, const rendering::ViewState &viewState, const rendering::RenderState &renderState)
BitmapEx getBitmap() const
Not threadsafe! Returned object is shared!
double getX() const
::BitmapEx transformBitmap(const BitmapEx &rBitmap, const ::basegfx::B2DHomMatrix &rTransform)
Definition: impltools.cxx:188
::basegfx::B2DRange & calcTransformedRectBounds(::basegfx::B2DRange &outRect, const ::basegfx::B2DRange &inRect, const ::basegfx::B2DHomMatrix &transformation)
Calc the bounding rectangle of a transformed rectangle.
double getY() const
::Point pointFromB2DPoint(const basegfx::B2DPoint &rPoint)
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XIntegerReadOnlyBitmap > &xInputBitmap)
AntialiasingFlags GetAntialiasing() const
tools::Long GetFontHeight() const
int nCount
bool setupFontTransform(::Point &o_rPoint, vcl::Font &io_rVCLFont, const rendering::ViewState &rViewState, const rendering::RenderState &rRenderState,::OutputDevice const &rOutDev)
Definition: impltools.cxx:87
FontMetric GetFontMetric() const
B2IRange fround(const B2DRange &rRange)
Product of this component's factory.
::tools::PolyPolygon mapPolyPolygon(const ::basegfx::B2DPolyPolygon &rPoly, const rendering::ViewState &rViewState, const rendering::RenderState &rRenderState)
Definition: impltools.cxx:172
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
void SetOrientation(Degree10 nLineOrientation)
AntialiasingFlags
void transform(const basegfx::B2DHomMatrix &rMatrix)
bool isRectangle(const ::tools::PolyPolygon &rPolyPoly)
Predicate, to determine whether polygon is actually an axis-aligned rectangle.
Definition: impltools.cxx:138
BitmapEx CanvasTransformBitmap(const BitmapEx &rBitmap, const ::basegfx::B2DHomMatrix &rTransform,::basegfx::B2DRectangle const &rDestRect,::basegfx::B2DHomMatrix const &rLocalTransform)
::basegfx::B2DHomMatrix & calcRectToOriginTransform(::basegfx::B2DHomMatrix &o_transform, const ::basegfx::B2DRange &i_srcRect, const ::basegfx::B2DHomMatrix &i_transformation)
Calc a transform that maps the upper, left corner of a rectangle to the origin.
#define ENSURE_OR_THROW(c, m)
VCL_DLLPUBLIC bool isVCLSkiaEnabled()
#define SAL_INFO(area, stream)
BackBufferSharedPtr const & getBackBuffer() const
Get window for this canvas.
void SetFontHeight(tools::Long nHeight)
const Size & GetSizePixel() const
tools::Long GetAverageFontWidth() const
::basegfx::B2DPoint b2DPointFromRealPoint2D(const geometry::RealPoint2D &rPoint)
void SetDefaultDeviceAntiAliasing(OutputDevice *pDevice)
Definition: impltools.cxx:221