- if (!_image) {
-
- _image = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _n_peaks, _wave_view->_height);
- Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create (_image);
-
- /* Draw the edge of the waveform, top half first, the loop back
- * for the bottom half to create a clockwise path
- */
-
- context->begin_new_path();
-
- if (_wave_view->_shape == WaveView::Rectified) {
-
- /* top edge of waveform is based on max (fabs (peak_min, peak_max))
- */
-
- if (_wave_view->_logscaled) {
- for (int i = 0; i < _n_peaks; ++i) {
- context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB (
- max (fabs (_peaks[i].max), fabs (_peaks[i].min))))));
- }
- } else {
- for (int i = 0; i < _n_peaks; ++i) {
- context->line_to (i + 0.5, position (max (fabs (_peaks[i].max), fabs (_peaks[i].min))));
- }
- }
-
- } else {
- if (_wave_view->_logscaled) {
- for (int i = 0; i < _n_peaks; ++i) {
- Coord y = _peaks[i].max;
-
- if (y > 0.0) {
- y = position (alt_log_meter (fast_coefficient_to_dB (y)));
- } else if (y < 0.0) {
- y = position (-alt_log_meter (fast_coefficient_to_dB (-y)));
- } else {
- y = position (0.0);
- }
- context->line_to (i + 0.5, y);
- }
- } else {
- for (int i = 0; i < _n_peaks; ++i) {
- context->line_to (i + 0.5, position (_peaks[i].max));
- }
- }
- }
-
- /* from final top point, move out of the clip zone */
-
- context->line_to (_n_peaks + 10, position (0.0));
-
- /* bottom half, in reverse */
-
- if (_wave_view->_shape == WaveView::Rectified) {
-
- /* lower half: drop to the bottom, then a line back to
- * beyond the left edge of the clip region
- */
-
- context->line_to (_n_peaks + 10, _wave_view->_height);
- context->line_to (-10.0, _wave_view->_height);
-
- } else {
-
- if (_wave_view->_logscaled) {
- for (int i = _n_peaks-1; i >= 0; --i) {
- Coord y = _peaks[i].min;
- if (y > 0.0) {
- context->line_to (i + 0.5, position (alt_log_meter (fast_coefficient_to_dB (y))));
- } else if (y < 0.0) {
- context->line_to (i + 0.5, position (-alt_log_meter (fast_coefficient_to_dB (-y))));
- } else {
- context->line_to (i + 0.5, position (0.0));
- }
- }
- } else {
- for (int i = _n_peaks-1; i >= 0; --i) {
- context->line_to (i + 0.5, position (_peaks[i].min));
- }
- }
-
- /* from final bottom point, move out of the clip zone */
-
- context->line_to (-10.0, position (0.0));
- }
-
- context->close_path ();
-
- if (_wave_view->gradient_depth() != 0.0) {
-
- Cairo::RefPtr<Cairo::LinearGradient> gradient (Cairo::LinearGradient::create (0, 0, 0, _wave_view->_height));
-
- double stops[3];
-
- double r, g, b, a;
-
- if (_wave_view->_shape == Rectified) {
- stops[0] = 0.1;
- stops[0] = 0.3;
- stops[0] = 0.9;
- } else {
- stops[0] = 0.1;
- stops[1] = 0.5;
- stops[2] = 0.9;
- }
-
- color_to_rgba (_wave_view->_fill_color, r, g, b, a);
- gradient->add_color_stop_rgba (stops[0], r, g, b, a);
- gradient->add_color_stop_rgba (stops[2], r, g, b, a);
-
- /* generate a new color for the middle of the gradient */
- double h, s, v;
- color_to_hsv (_wave_view->_fill_color, h, s, v);
- /* tone down the saturation */
- s *= 1.0 - _wave_view->gradient_depth();
- Color center = hsv_to_color (h, s, v, a);
- color_to_rgba (center, r, g, b, a);
- gradient->add_color_stop_rgba (stops[1], r, g, b, a);
-
- context->set_source (gradient);
- } else {
- set_source_rgba (context, _wave_view->_fill_color);
- }
-
- context->fill_preserve ();
- _wave_view->setup_outline_context (context);
- context->stroke ();
-
- if (_wave_view->show_zero_line()) {
- set_source_rgba (context, _wave_view->_zero_color);
- context->move_to (0, position (0.0));
- context->line_to (_n_peaks, position (0.0));
- context->stroke ();
- }
- }
-
- return _image;
-}