2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 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 const double Pi
= 3.14159265358979323846264338328;
33 #define HALF(X) (((X) + 1) / 2)
34 #define DEFAULT_DEPTH 10
36 CBarShader::CBarShader(unsigned height
, unsigned width
)
41 m_used3dlevel( DEFAULT_DEPTH
),
47 CBarShader::~CBarShader()
55 void CBarShader::SetHeight(unsigned height
)
57 if( m_Height
!= height
) {
69 void CBarShader::SetWidth(int width
)
73 Fill(CMuleColour(0,0,0));
78 void CBarShader::Set3dDepth(unsigned depth
)
82 } else if ( depth
> 5 ) {
86 if ( m_used3dlevel
!= depth
) {
87 m_used3dlevel
= depth
;
98 void CBarShader::BuildModifiers()
100 wxASSERT(m_used3dlevel
< 7);
103 delete[] m_Modifiers
;
106 unsigned depth
= (7 - m_used3dlevel
);
107 unsigned count
= HALF(m_Height
);
108 double piOverDepth
= Pi
/depth
;
109 double base
= piOverDepth
* ((depth
/ 2.0) - 1);
110 double increment
= piOverDepth
/ (count
- 1);
112 m_Modifiers
= new double[count
];
113 for (unsigned i
= 0; i
< count
; i
++)
114 m_Modifiers
[i
] = (double)(sin(base
+ i
* increment
));
118 void CBarShader::FillRange(uint64 start
, uint64 end
, const CMuleColour
& colour
)
120 wxASSERT(m_FileSize
> 0);
122 if (start
>= end
|| start
>= m_FileSize
) {
126 // precision for small files: end must be increased by one
127 // think of each byte as a visible block, then start points to
128 // the beginning of its block, but end points to the END of its block
131 if (end
> m_FileSize
) {
135 unsigned firstPixel
= start
* m_Width
/ m_FileSize
;
136 unsigned lastPixel
= end
* m_Width
/ m_FileSize
;
137 if (lastPixel
== m_Width
) {
141 double f_Width
= m_Width
;
142 // calculate how much of this pixels is to be covered with the fill
143 double firstCovered
= firstPixel
+ 1 - start
* f_Width
/ m_FileSize
;
144 double lastCovered
= end
* f_Width
/ m_FileSize
- lastPixel
;
145 // all inside one pixel ?
146 if (firstPixel
== lastPixel
) {
147 m_Content
[firstPixel
].BlendWith(colour
, firstCovered
+ lastCovered
- 1.0);
149 m_Content
[firstPixel
].BlendWith(colour
, firstCovered
);
150 m_Content
[lastPixel
].BlendWith(colour
, lastCovered
);
151 // fill pixels between (if any)
152 for (unsigned i
= firstPixel
+ 1; i
< lastPixel
; i
++) {
153 m_Content
[i
] = colour
;
159 void CBarShader::Draw( wxDC
* dc
, int iLeft
, int iTop
, bool bFlat
)
163 // Do we need to rebuild the modifiers?
164 if ( !bFlat
&& !m_Modifiers
) {
168 // Render the bar into a raw buffer
169 unsigned char * buf
= (unsigned char *) malloc(m_Width
* m_Height
* 3);
174 for (unsigned x
= 0; x
< m_Width
; x
++) {
175 unsigned cRed
= m_Content
[x
].Red();
176 unsigned cGreen
= m_Content
[x
].Green();
177 unsigned cBlue
= m_Content
[x
].Blue();
182 unsigned linelength
= idx
;
184 for (; y
< m_Height
>> 1; y
<<= 1, idx
<<= 1) {
185 std::memcpy(buf
+ idx
, buf
, idx
);
188 std::memcpy(buf
+ idx
, buf
, (m_Height
- y
) * linelength
);
192 unsigned Max
= HALF(m_Height
);
194 for (unsigned y
= 0; y
< Max
; y
++) {
195 for (unsigned x
= 0; x
< m_Width
; x
++) {
196 unsigned cRed
= (unsigned)(m_Content
[x
].Red() * m_Modifiers
[y
] + .5f
);
197 unsigned cGreen
= (unsigned)(m_Content
[x
].Green() * m_Modifiers
[y
] + .5f
);
198 unsigned cBlue
= (unsigned)(m_Content
[x
].Blue() * m_Modifiers
[y
] + .5f
);
199 cRed
= std::min(255u, cRed
);
200 cGreen
= std::min(255u, cGreen
);
201 cBlue
= std::min(255u, cBlue
);
207 unsigned linelength
= m_Width
* 3;
208 for (unsigned y
= std::max(Max
, m_Height
- Max
); y
< m_Height
; y
++) {
209 std::memcpy(buf
+ y
* linelength
, buf
+ (m_Height
- 1 - y
) * linelength
, linelength
);
212 wxImage
image(m_Width
, m_Height
);
214 wxBitmap
bitmap(image
);
215 dc
->DrawBitmap(bitmap
, iLeft
, iTop
);
217 // File_checked_for_headers