1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "dx_bitmap.hxx"
22 #include "dx_graphicsprovider.hxx"
23 #include "dx_impltools.hxx"
25 #include <canvas/debug.hxx>
26 #include <tools/diagnose_ex.h>
28 #include <basegfx/matrix/b2dhommatrix.hxx>
29 #include <basegfx/range/b2irange.hxx>
31 #if defined(DX_DEBUG_IMAGES)
32 # if OSL_DEBUG_LEVEL > 0
39 using namespace ::com::sun::star
;
47 DXBitmap::DXBitmap( const BitmapSharedPtr
& rBitmap
,
49 mpGdiPlusUser( GDIPlusUser::createInstance() ),
50 maSize(rBitmap
->GetWidth(),rBitmap
->GetHeight()),
52 mpGraphics(tools::createGraphicsFromBitmap(mpBitmap
)),
57 DXBitmap::DXBitmap( const ::basegfx::B2IVector
& rSize
,
59 mpGdiPlusUser( GDIPlusUser::createInstance() ),
65 // create container for pixel data
72 PixelFormat32bppARGB
));
80 PixelFormat24bppRGB
));
83 mpGraphics
.reset( tools::createGraphicsFromBitmap(mpBitmap
) );
86 BitmapSharedPtr
DXBitmap::getBitmap() const
91 GraphicsSharedPtr
DXBitmap::getGraphics()
96 ::basegfx::B2IVector
DXBitmap::getSize() const
101 bool DXBitmap::hasAlpha() const
106 uno::Sequence
< sal_Int8
> DXBitmap::getData( rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
107 const geometry::IntegerRectangle2D
& rect
)
109 uno::Sequence
< sal_Int8
> aRes( (rect
.X2
-rect
.X1
)*(rect
.Y2
-rect
.Y1
)*4 ); // TODO(F1): Be format-agnostic here
111 const Gdiplus::Rect
aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect
) );
113 Gdiplus::BitmapData aBmpData
;
114 aBmpData
.Width
= rect
.X2
-rect
.X1
;
115 aBmpData
.Height
= rect
.Y2
-rect
.Y1
;
116 aBmpData
.Stride
= 4*aBmpData
.Width
;
117 aBmpData
.PixelFormat
= PixelFormat32bppARGB
;
118 aBmpData
.Scan0
= aRes
.getArray();
120 // TODO(F1): Support more pixel formats natively
122 // read data from bitmap
123 if( Gdiplus::Ok
!= mpBitmap
->LockBits( &aRect
,
124 Gdiplus::ImageLockModeRead
| Gdiplus::ImageLockModeUserInputBuf
,
125 PixelFormat32bppARGB
, // TODO(F1): Adapt to
131 // failed to lock, bail out
132 return uno::Sequence
< sal_Int8
>();
135 mpBitmap
->UnlockBits( &aBmpData
);
140 void DXBitmap::setData( const uno::Sequence
< sal_Int8
>& data
,
141 const rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
142 const geometry::IntegerRectangle2D
& rect
)
144 const Gdiplus::Rect
aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect
) );
146 Gdiplus::BitmapData aBmpData
;
147 aBmpData
.Width
= rect
.X2
-rect
.X1
;
148 aBmpData
.Height
= rect
.Y2
-rect
.Y1
;
149 aBmpData
.Stride
= 4*aBmpData
.Width
;
150 aBmpData
.PixelFormat
= PixelFormat32bppARGB
;
151 aBmpData
.Scan0
= (void*)data
.getConstArray();
153 // TODO(F1): Support more pixel formats natively
155 if( Gdiplus::Ok
!= mpBitmap
->LockBits( &aRect
,
156 Gdiplus::ImageLockModeWrite
| Gdiplus::ImageLockModeUserInputBuf
,
157 PixelFormat32bppARGB
, // TODO: Adapt to
163 throw uno::RuntimeException();
166 // commit data to bitmap
167 mpBitmap
->UnlockBits( &aBmpData
);
170 void DXBitmap::setPixel( const uno::Sequence
< sal_Int8
>& color
,
171 const rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
172 const geometry::IntegerPoint2D
& pos
)
174 const geometry::IntegerSize2D
aSize( maSize
.getX(),maSize
.getY() );
176 ENSURE_ARG_OR_THROW( pos
.X
>= 0 && pos
.X
< aSize
.Width
,
177 "CanvasHelper::setPixel: X coordinate out of bounds" );
178 ENSURE_ARG_OR_THROW( pos
.Y
>= 0 && pos
.Y
< aSize
.Height
,
179 "CanvasHelper::setPixel: Y coordinate out of bounds" );
180 ENSURE_ARG_OR_THROW( color
.getLength() > 3,
181 "CanvasHelper::setPixel: not enough color components" );
183 if( Gdiplus::Ok
!= mpBitmap
->SetPixel( pos
.X
, pos
.Y
,
184 Gdiplus::Color( tools::sequenceToArgb( color
))))
186 throw uno::RuntimeException();
190 uno::Sequence
< sal_Int8
> DXBitmap::getPixel( rendering::IntegerBitmapLayout
& /*bitmapLayout*/,
191 const geometry::IntegerPoint2D
& pos
)
193 const geometry::IntegerSize2D
aSize( maSize
.getX(),maSize
.getY() );
195 ENSURE_ARG_OR_THROW( pos
.X
>= 0 && pos
.X
< aSize
.Width
,
196 "CanvasHelper::getPixel: X coordinate out of bounds" );
197 ENSURE_ARG_OR_THROW( pos
.Y
>= 0 && pos
.Y
< aSize
.Height
,
198 "CanvasHelper::getPixel: Y coordinate out of bounds" );
200 Gdiplus::Color aColor
;
202 if( Gdiplus::Ok
!= mpBitmap
->GetPixel( pos
.X
, pos
.Y
, &aColor
) )
203 return uno::Sequence
< sal_Int8
>();
205 return tools::argbToIntSequence(aColor
.GetValue());
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */