Branch libreoffice-5-0-4
[LibreOffice.git] / canvas / source / directx / dx_bitmap.cxx
blob145848eea05a241fdc80f01c2b02fb53c1ec1424
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
33 # include <imdebug.h>
34 # undef min
35 # undef max
36 # endif
37 #endif
39 using namespace ::com::sun::star;
41 namespace dxcanvas
44 // DXBitmap::DXBitmap
47 DXBitmap::DXBitmap( const BitmapSharedPtr& rBitmap,
48 bool bWithAlpha ) :
49 mpGdiPlusUser( GDIPlusUser::createInstance() ),
50 maSize(rBitmap->GetWidth(),rBitmap->GetHeight()),
51 mpBitmap(rBitmap),
52 mpGraphics(tools::createGraphicsFromBitmap(mpBitmap)),
53 mbAlpha(bWithAlpha)
57 DXBitmap::DXBitmap( const ::basegfx::B2IVector& rSize,
58 bool bWithAlpha ) :
59 mpGdiPlusUser( GDIPlusUser::createInstance() ),
60 maSize(rSize),
61 mpBitmap(),
62 mpGraphics(),
63 mbAlpha(bWithAlpha)
65 // create container for pixel data
66 if(mbAlpha)
68 mpBitmap.reset(
69 new Gdiplus::Bitmap(
70 maSize.getX(),
71 maSize.getY(),
72 PixelFormat32bppARGB));
74 else
76 mpBitmap.reset(
77 new Gdiplus::Bitmap(
78 maSize.getX(),
79 maSize.getY(),
80 PixelFormat24bppRGB));
83 mpGraphics.reset( tools::createGraphicsFromBitmap(mpBitmap) );
86 BitmapSharedPtr DXBitmap::getBitmap() const
88 return mpBitmap;
91 GraphicsSharedPtr DXBitmap::getGraphics()
93 return mpGraphics;
96 ::basegfx::B2IVector DXBitmap::getSize() const
98 return maSize;
101 bool DXBitmap::hasAlpha() const
103 return mbAlpha;
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
126 // Graphics native
127 // format/change
128 // getMemoryLayout
129 &aBmpData ) )
131 // failed to lock, bail out
132 return uno::Sequence< sal_Int8 >();
135 mpBitmap->UnlockBits( &aBmpData );
137 return aRes;
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
158 // Graphics native
159 // format/change
160 // getMemoryLayout
161 &aBmpData ) )
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: */