2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "BarShader.h" // Interface declarations.
29 #include <cstring> // Needed for std::memcpy
31 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
32 #include <algorithm> // for std::min and std::max
35 const double Pi
= 3.14159265358979323846264338328;
37 #define HALF(X) (((X) + 1) / 2)
38 #define DEFAULT_DEPTH 10
40 CBarShader::CBarShader(unsigned height
, unsigned width
)
45 m_used3dlevel( DEFAULT_DEPTH
),
51 CBarShader::~CBarShader()
59 void CBarShader::SetHeight(unsigned height
)
61 if( m_Height
!= height
) {
73 void CBarShader::SetWidth(int width
)
77 Fill(CMuleColour(0,0,0));
82 void CBarShader::Set3dDepth(unsigned depth
)
86 } else if ( depth
> 5 ) {
90 if ( m_used3dlevel
!= depth
) {
91 m_used3dlevel
= depth
;
102 void CBarShader::BuildModifiers()
104 wxASSERT(m_used3dlevel
< 7);
107 delete[] m_Modifiers
;
110 unsigned depth
= (7 - m_used3dlevel
);
111 unsigned count
= HALF(m_Height
);
112 double piOverDepth
= Pi
/depth
;
113 double base
= piOverDepth
* ((depth
/ 2.0) - 1);
114 double increment
= piOverDepth
/ (count
- 1);
116 m_Modifiers
= new double[count
];
117 for (unsigned i
= 0; i
< count
; i
++)
118 m_Modifiers
[i
] = (double)(sin(base
+ i
* increment
));
122 void CBarShader::FillRange(uint64 start
, uint64 end
, const CMuleColour
& colour
)
124 wxASSERT(m_FileSize
> 0);
126 if (start
>= end
|| start
>= m_FileSize
) {
130 // precision for small files: end must be increased by one
131 // think of each byte as a visible block, then start points to
132 // the beginning of its block, but end points to the END of its block
135 if (end
> m_FileSize
) {
139 unsigned firstPixel
= start
* m_Width
/ m_FileSize
;
140 unsigned lastPixel
= end
* m_Width
/ m_FileSize
;
141 if (lastPixel
== m_Width
) {
145 double f_Width
= m_Width
;
146 // calculate how much of this pixels is to be covered with the fill
147 double firstCovered
= firstPixel
+ 1 - start
* f_Width
/ m_FileSize
;
148 double lastCovered
= end
* f_Width
/ m_FileSize
- lastPixel
;
149 // all inside one pixel ?
150 if (firstPixel
== lastPixel
) {
151 m_Content
[firstPixel
].BlendWith(colour
, firstCovered
+ lastCovered
- 1.0);
153 m_Content
[firstPixel
].BlendWith(colour
, firstCovered
);
154 m_Content
[lastPixel
].BlendWith(colour
, lastCovered
);
155 // fill pixels between (if any)
156 for (unsigned i
= firstPixel
+ 1; i
< lastPixel
; i
++) {
157 m_Content
[i
] = colour
;
163 void CBarShader::Draw( wxDC
* dc
, int iLeft
, int iTop
, bool bFlat
)
167 // Do we need to rebuild the modifiers?
168 if ( !bFlat
&& !m_Modifiers
) {
172 // Render the bar into a raw buffer
173 unsigned char * buf
= (unsigned char *) malloc(m_Width
* m_Height
* 3);
178 for (unsigned x
= 0; x
< m_Width
; x
++) {
179 unsigned cRed
= m_Content
[x
].Red();
180 unsigned cGreen
= m_Content
[x
].Green();
181 unsigned cBlue
= m_Content
[x
].Blue();
186 unsigned linelength
= idx
;
188 for (; y
< m_Height
>> 1; y
<<= 1, idx
<<= 1) {
189 std::memcpy(buf
+ idx
, buf
, idx
);
192 std::memcpy(buf
+ idx
, buf
, (m_Height
- y
) * linelength
);
196 unsigned Max
= HALF(m_Height
);
198 for (unsigned y
= 0; y
< Max
; y
++) {
199 for (unsigned x
= 0; x
< m_Width
; x
++) {
200 unsigned cRed
= (unsigned)(m_Content
[x
].Red() * m_Modifiers
[y
] + .5f
);
201 unsigned cGreen
= (unsigned)(m_Content
[x
].Green() * m_Modifiers
[y
] + .5f
);
202 unsigned cBlue
= (unsigned)(m_Content
[x
].Blue() * m_Modifiers
[y
] + .5f
);
203 cRed
= std::min(255u, cRed
);
204 cGreen
= std::min(255u, cGreen
);
205 cBlue
= std::min(255u, cBlue
);
211 unsigned linelength
= m_Width
* 3;
212 for (unsigned y
= std::max(Max
, m_Height
- Max
); y
< m_Height
; y
++) {
213 std::memcpy(buf
+ y
* linelength
, buf
+ (m_Height
- 1 - y
) * linelength
, linelength
);
216 wxImage
image(m_Width
, m_Height
);
218 wxBitmap
bitmap(image
);
219 dc
->DrawBitmap(bitmap
, iLeft
, iTop
);
221 // File_checked_for_headers