LibreOffice Module canvas (master)  1
dx_bitmap.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 
24 #include <tools/diagnose_ex.h>
25 
26 #include "dx_bitmap.hxx"
27 #include "dx_graphicsprovider.hxx"
28 #include "dx_impltools.hxx"
29 
30 using namespace ::com::sun::star;
31 
32 namespace dxcanvas
33 {
34 
35  // DXBitmap::DXBitmap
36 
37 
39  bool bWithAlpha ) :
40  mpGdiPlusUser( GDIPlusUser::createInstance() ),
41  maSize(rBitmap->GetWidth(),rBitmap->GetHeight()),
42  mpBitmap(rBitmap),
44  mbAlpha(bWithAlpha)
45  {
46  }
47 
48  DXBitmap::DXBitmap( const ::basegfx::B2IVector& rSize,
49  bool bWithAlpha ) :
50  mpGdiPlusUser( GDIPlusUser::createInstance() ),
51  maSize(rSize),
52  mpBitmap(),
53  mpGraphics(),
54  mbAlpha(bWithAlpha)
55  {
56  // create container for pixel data
57  if(mbAlpha)
58  {
59  mpBitmap.reset(
60  new Gdiplus::Bitmap(
61  maSize.getX(),
62  maSize.getY(),
63  PixelFormat32bppARGB));
64  }
65  else
66  {
67  mpBitmap.reset(
68  new Gdiplus::Bitmap(
69  maSize.getX(),
70  maSize.getY(),
71  PixelFormat24bppRGB));
72  }
73 
75  }
76 
78  {
79  return mpBitmap;
80  }
81 
83  {
84  return mpGraphics;
85  }
86 
88  {
89  return maSize;
90  }
91 
92  bool DXBitmap::hasAlpha() const
93  {
94  return mbAlpha;
95  }
96 
97  uno::Sequence< sal_Int8 > DXBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
98  const geometry::IntegerRectangle2D& rect )
99  {
100  uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here
101 
102  const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
103 
104  Gdiplus::BitmapData aBmpData;
105  aBmpData.Width = rect.X2-rect.X1;
106  aBmpData.Height = rect.Y2-rect.Y1;
107  aBmpData.Stride = 4*aBmpData.Width;
108  aBmpData.PixelFormat = PixelFormat32bppARGB;
109  aBmpData.Scan0 = aRes.getArray();
110 
111  // TODO(F1): Support more pixel formats natively
112 
113  // read data from bitmap
114  if( Gdiplus::Ok != mpBitmap->LockBits( &aRect,
115  Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
116  PixelFormat32bppARGB, // TODO(F1): Adapt to
117  // Graphics native
118  // format/change
119  // getMemoryLayout
120  &aBmpData ) )
121  {
122  // failed to lock, bail out
123  return uno::Sequence< sal_Int8 >();
124  }
125 
126  mpBitmap->UnlockBits( &aBmpData );
127 
128  return aRes;
129  }
130 
131  void DXBitmap::setData( const uno::Sequence< sal_Int8 >& data,
132  const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
133  const geometry::IntegerRectangle2D& rect )
134  {
135  const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) );
136 
137  Gdiplus::BitmapData aBmpData;
138  aBmpData.Width = rect.X2-rect.X1;
139  aBmpData.Height = rect.Y2-rect.Y1;
140  aBmpData.Stride = 4*aBmpData.Width;
141  aBmpData.PixelFormat = PixelFormat32bppARGB;
142  aBmpData.Scan0 = const_cast<sal_Int8 *>(data.getConstArray());
143  // const_cast is safe, "Gdiplus::ImageLockModeWrite
144  // | Gdiplus::ImageLockModeUserInputBuf makes the data go from
145  // BitmapData into Bitmap", says Thorsten
146 
147  // TODO(F1): Support more pixel formats natively
148 
149  if( Gdiplus::Ok != mpBitmap->LockBits( &aRect,
150  Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf,
151  PixelFormat32bppARGB, // TODO: Adapt to
152  // Graphics native
153  // format/change
154  // getMemoryLayout
155  &aBmpData ) )
156  {
157  throw uno::RuntimeException();
158  }
159 
160  // commit data to bitmap
161  mpBitmap->UnlockBits( &aBmpData );
162  }
163 
164  void DXBitmap::setPixel( const uno::Sequence< sal_Int8 >& color,
165  const rendering::IntegerBitmapLayout& /*bitmapLayout*/,
166  const geometry::IntegerPoint2D& pos )
167  {
168  const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
169 
170  ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
171  "CanvasHelper::setPixel: X coordinate out of bounds" );
172  ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
173  "CanvasHelper::setPixel: Y coordinate out of bounds" );
174  ENSURE_ARG_OR_THROW( color.getLength() > 3,
175  "CanvasHelper::setPixel: not enough color components" );
176 
177  if( Gdiplus::Ok != mpBitmap->SetPixel( pos.X, pos.Y,
178  Gdiplus::Color( tools::sequenceToArgb( color ))))
179  {
180  throw uno::RuntimeException();
181  }
182  }
183 
184  uno::Sequence< sal_Int8 > DXBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/,
185  const geometry::IntegerPoint2D& pos )
186  {
187  const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() );
188 
189  ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width,
190  "CanvasHelper::getPixel: X coordinate out of bounds" );
191  ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height,
192  "CanvasHelper::getPixel: Y coordinate out of bounds" );
193 
194  Gdiplus::Color aColor;
195 
196  if( Gdiplus::Ok != mpBitmap->GetPixel( pos.X, pos.Y, &aColor ) )
197  return uno::Sequence< sal_Int8 >();
198 
199  return tools::argbToIntSequence(aColor.GetValue());
200  }
201 
202 }
203 
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
BitmapSharedPtr mpBitmap
Definition: dx_bitmap.hxx:75
::basegfx::B2IVector maSize
Definition: dx_bitmap.hxx:73
css::uno::Sequence< sal_Int8 > getPixel(css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerPoint2D &pos) override
Definition: dx_bitmap.cxx:184
signed char sal_Int8
virtual bool hasAlpha() const override
Definition: dx_bitmap.cxx:92
virtual GraphicsSharedPtr getGraphics() override
Definition: dx_bitmap.cxx:82
Gdiplus::Graphics * createGraphicsFromBitmap(const BitmapSharedPtr &rBitmap)
void setData(const css::uno::Sequence< sal_Int8 > &data, const css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerRectangle2D &rect) override
Definition: dx_bitmap.cxx:131
Gdiplus::ARGB sequenceToArgb(const uno::Sequence< sal_Int8 > &rColor)
css::uno::Sequence< sal_Int8 > getData(css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerRectangle2D &rect) override
Definition: dx_bitmap.cxx:97
Gdiplus::Rect gdiPlusRectFromIntegerRectangle2D(const geometry::IntegerRectangle2D &rRect)
virtual BitmapSharedPtr getBitmap() const override
Definition: dx_bitmap.cxx:77
virtual ::basegfx::B2IVector getSize() const override
Definition: dx_bitmap.cxx:87
GraphicsSharedPtr mpGraphics
Definition: dx_canvas.cxx:66
sal_Int32 getX() const
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
Gdiplus::BitmapData aBmpData
#define ENSURE_ARG_OR_THROW(c, m)
void setPixel(const css::uno::Sequence< sal_Int8 > &color, const css::rendering::IntegerBitmapLayout &bitmapLayout, const css::geometry::IntegerPoint2D &pos) override
Definition: dx_bitmap.cxx:164
std::shared_ptr< Gdiplus::Bitmap > BitmapSharedPtr
Definition: dx_winstuff.hxx:63
uno::Sequence< sal_Int8 > argbToIntSequence(Gdiplus::ARGB rColor)
GraphicsSharedPtr mpGraphics
Definition: dx_bitmap.hxx:76
sal_Int32 getY() const
DXBitmap(const BitmapSharedPtr &rBitmap, bool bWithAlpha)
Definition: dx_bitmap.cxx:38
::basegfx::B2IVector maSize
Definition: dx_9rm.cxx:115
std::shared_ptr< Gdiplus::Graphics > GraphicsSharedPtr
Definition: dx_winstuff.hxx:61