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 
37 #include <canvas/canvastools.hxx>
38 
39 #include "canvasbitmap.hxx"
40 #include "impltools.hxx"
41 #include "spritecanvas.hxx"
42 
43 
44 using namespace ::com::sun::star;
45 
47 {
48  ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XBitmap >& xBitmap )
49  {
50  // TODO(F3): CanvasCustomSprite should also be tunnelled
51  // through (also implements XIntegerBitmap interface)
52  CanvasBitmap* pBitmapImpl = dynamic_cast< CanvasBitmap* >( xBitmap.get() );
53 
54  if( pBitmapImpl )
55  {
56  return pBitmapImpl->getBitmap();
57  }
58  else
59  {
60  SpriteCanvas* pCanvasImpl = dynamic_cast< SpriteCanvas* >( xBitmap.get() );
61  if( pCanvasImpl && pCanvasImpl->getBackBuffer() )
62  {
63  // TODO(F3): mind the plain Canvas impl. Consolidate with CWS canvas05
64  const ::OutputDevice& rDev( pCanvasImpl->getBackBuffer()->getOutDev() );
65  const ::Point aEmptyPoint;
66  return rDev.GetBitmapEx( aEmptyPoint,
67  rDev.GetOutputSizePixel() );
68  }
69 
70  // TODO(F2): add support for floating point bitmap formats
71  uno::Reference< rendering::XIntegerReadOnlyBitmap > xIntBmp(
72  xBitmap, uno::UNO_QUERY_THROW );
73 
75  if( !!aBmpEx )
76  return aBmpEx;
77 
78  // TODO(F1): extract pixel from XBitmap interface
79  ENSURE_OR_THROW( false,
80  "bitmapExFromXBitmap(): could not extract bitmap" );
81  }
82 
83  return ::BitmapEx();
84  }
85 
86  bool setupFontTransform( ::Point& o_rPoint,
87  vcl::Font& io_rVCLFont,
88  const rendering::ViewState& rViewState,
89  const rendering::RenderState& rRenderState,
90  ::OutputDevice const & rOutDev )
91  {
93 
95  rViewState,
96  rRenderState);
97 
98  ::basegfx::B2DTuple aScale;
99  ::basegfx::B2DTuple aTranslate;
100  double nRotate, nShearX;
101 
102  aMatrix.decompose( aScale, aTranslate, nRotate, nShearX );
103 
104  // query font metric _before_ tampering with width and height
105  if( !::rtl::math::approxEqual(aScale.getX(), aScale.getY()) )
106  {
107  // retrieve true font width
108  const sal_Int32 nFontWidth( rOutDev.GetFontMetric( io_rVCLFont ).GetAverageFontWidth() );
109 
110  const sal_Int32 nScaledFontWidth( ::basegfx::fround(nFontWidth * aScale.getX()) );
111 
112  if( !nScaledFontWidth )
113  {
114  // scale is smaller than one pixel - disable text
115  // output altogether
116  return false;
117  }
118 
119  io_rVCLFont.SetAverageFontWidth( nScaledFontWidth );
120  }
121 
122  if( !::rtl::math::approxEqual(aScale.getY(), 1.0) )
123  {
124  const sal_Int32 nFontHeight( io_rVCLFont.GetFontHeight() );
125  io_rVCLFont.SetFontHeight( ::basegfx::fround(nFontHeight * aScale.getY()) );
126  }
127 
128  io_rVCLFont.SetOrientation( static_cast< short >( ::basegfx::fround(-fmod(nRotate, 2*M_PI)*(1800.0/M_PI)) ) );
129 
130  // TODO(F2): Missing functionality in VCL: shearing
131  o_rPoint.setX( ::basegfx::fround(aTranslate.getX()) );
132  o_rPoint.setY( ::basegfx::fround(aTranslate.getY()) );
133 
134  return true;
135  }
136 
137  bool isRectangle( const ::tools::PolyPolygon& rPolyPoly )
138  {
139  // exclude some cheap cases first
140  if( rPolyPoly.Count() != 1 )
141  return false;
142 
143  const ::tools::Polygon& rPoly( rPolyPoly[0] );
144 
145  sal_uInt16 nCount( rPoly.GetSize() );
146  if( nCount < 4 )
147  return false;
148 
149  // delegate to basegfx
150  return ::basegfx::utils::isRectangle( rPoly.getB2DPolygon() );
151  }
152 
153 
154  // VCL-Canvas related
155 
156 
157  ::Point mapRealPoint2D( const geometry::RealPoint2D& rPoint,
158  const rendering::ViewState& rViewState,
159  const rendering::RenderState& rRenderState )
160  {
162 
163  ::basegfx::B2DHomMatrix aMatrix;
165  rViewState,
166  rRenderState);
167 
168  return vcl::unotools::pointFromB2DPoint( aPoint );
169  }
170 
171  ::tools::PolyPolygon mapPolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly,
172  const rendering::ViewState& rViewState,
173  const rendering::RenderState& rRenderState )
174  {
175  ::basegfx::B2DHomMatrix aMatrix;
177  rViewState,
178  rRenderState);
179 
180  ::basegfx::B2DPolyPolygon aTemp( rPoly );
181 
182  aTemp.transform( aMatrix );
183 
184  return ::tools::PolyPolygon( aTemp );
185  }
186 
188  const ::basegfx::B2DHomMatrix& rTransform )
189  {
190  SAL_INFO( "canvas.vcl", "::vclcanvas::tools::transformBitmap()" );
191  SAL_INFO( "canvas.vcl", "::vclcanvas::tools::transformBitmap: 0x" << std::hex << &rBitmap );
192 
193  // calc transformation and size of bitmap to be
194  // generated. Note, that the translational components are
195  // deleted from the transformation; this can be handled by
196  // an offset when painting the bitmap
197  const Size aBmpSize( rBitmap.GetSizePixel() );
198  ::basegfx::B2DRectangle aDestRect;
199 
200  // calc effective transformation for bitmap
201  const ::basegfx::B2DRectangle aSrcRect( 0, 0,
202  aBmpSize.Width(),
203  aBmpSize.Height() );
205  aSrcRect,
206  rTransform );
207 
208  // re-center bitmap, such that it's left, top border is
209  // aligned with (0,0). The method takes the given
210  // rectangle, and calculates a transformation that maps
211  // this rectangle unscaled to the origin.
212  ::basegfx::B2DHomMatrix aLocalTransform;
214  aSrcRect,
215  rTransform );
216 
217  return vcl::bitmap::CanvasTransformBitmap(rBitmap, rTransform, aDestRect, aLocalTransform);
218  }
219 }
220 
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::Point mapRealPoint2D(const geometry::RealPoint2D &rPoint, const rendering::ViewState &rViewState, const rendering::RenderState &rRenderState)
Definition: impltools.cxx:157
void SetAverageFontWidth(long nWidth)
long GetFontHeight() const
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XBitmap > &xBitmap)
Definition: impltools.cxx:48
::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:187
::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)
void SetOrientation(short nLineOrientation)
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:86
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:171
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
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:137
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)
#define SAL_INFO(area, stream)
void SetFontHeight(long nHeight)
BackBufferSharedPtr const & getBackBuffer() const
Get window for this canvas.
long GetAverageFontWidth() const
const Size & GetSizePixel() const
::basegfx::B2DPoint b2DPointFromRealPoint2D(const geometry::RealPoint2D &rPoint)