-void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp)
-{
- QLineF *line;
-
- vector< pair<int64_t, bool> > edges;
-
- assert(base_);
-
- const int y = get_visual_y();
-
- if (!base_->enabled() || !base_->logic_data())
- return;
-
- const int signal_margin =
- QFontMetrics(QApplication::font()).height() / 2;
-
- const int ph = min(pos_vdivs_, 1) * div_height_;
- const int nh = min(neg_vdivs_, 1) * div_height_;
- const float high_offset = y - ph + signal_margin + 0.5f;
- const float low_offset = y + nh - signal_margin - 0.5f;
-
- shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
- if (!segment || (segment->get_sample_count() == 0))
- return;
-
- double samplerate = segment->samplerate();
-
- // Show sample rate as 1Hz when it is unknown
- if (samplerate == 0.0)
- samplerate = 1.0;
-
- const double pixels_offset = pp.pixels_offset();
- const pv::util::Timestamp& start_time = segment->start_time();
- const int64_t last_sample = (int64_t)segment->get_sample_count() - 1;
- const double samples_per_pixel = samplerate * pp.scale();
- const double pixels_per_sample = 1 / samples_per_pixel;
- const pv::util::Timestamp start = samplerate * (pp.offset() - start_time);
- const pv::util::Timestamp end = start + samples_per_pixel * pp.width();
-
- const int64_t start_sample = min(max(floor(start).convert_to<int64_t>(),
- (int64_t)0), last_sample);
- const uint64_t end_sample = min(max(ceil(end).convert_to<int64_t>(),
- (int64_t)0), last_sample);
-
- segment->get_subsampled_edges(edges, start_sample, end_sample,
- samples_per_pixel / LogicSignal::Oversampling, 0);
- assert(edges.size() >= 2);
-
- // Check whether we need to paint the sampling points
- GlobalSettings settings;
- const bool show_sampling_points =
- settings.value(GlobalSettings::Key_View_ShowSamplingPoints).toBool() &&
- (samples_per_pixel < 0.25);
-
- vector<QRectF> sampling_points;
- float sampling_point_x = 0.0f;
- int64_t sampling_point_sample = start_sample;
- const int w = 2;
-
- if (show_sampling_points) {
- sampling_points.reserve(end_sample - start_sample + 1);
- sampling_point_x = (edges.cbegin()->first / samples_per_pixel - pixels_offset) + pp.left();
- }
-
- // Paint the edges
- const unsigned int edge_count = edges.size() - 2;
- QLineF *const edge_lines = new QLineF[edge_count];
- line = edge_lines;
-
- for (auto i = edges.cbegin() + 1; i != edges.cend() - 1; i++) {
- const float x = ((*i).first / samples_per_pixel -
- pixels_offset) + pp.left();
- *line++ = QLineF(x, high_offset, x, low_offset);
-
- if (show_sampling_points)
- while (sampling_point_sample < (*i).first) {
- const float y = (*i).second ? low_offset : high_offset;
- sampling_points.emplace_back(
- QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w));
- sampling_point_sample++;
- sampling_point_x += pixels_per_sample;
- };
- }
-
- // Calculate the sample points from the last edge to the end of the trace
- if (show_sampling_points)
- while ((uint64_t)sampling_point_sample <= end_sample) {
- // Signal changed after the last edge, so the level is inverted
- const float y = (edges.cend() - 1)->second ? high_offset : low_offset;
- sampling_points.emplace_back(
- QRectF(sampling_point_x - (w / 2), y - (w / 2), w, w));
- sampling_point_sample++;
- sampling_point_x += pixels_per_sample;
- };
-
- p.setPen(LogicSignal::EdgeColor);
- p.drawLines(edge_lines, edge_count);
- delete[] edge_lines;
-
- // Paint the caps
- const unsigned int max_cap_line_count = edges.size();
- QLineF *const cap_lines = new QLineF[max_cap_line_count];
-
- p.setPen(LogicSignal::HighColor);
- paint_logic_caps(p, cap_lines, edges, true, samples_per_pixel,
- pixels_offset, pp.left(), high_offset);
- p.setPen(LogicSignal::LowColor);
- paint_logic_caps(p, cap_lines, edges, false, samples_per_pixel,
- pixels_offset, pp.left(), low_offset);
-
- delete[] cap_lines;
-
- // Paint the sampling points
- if (show_sampling_points) {
- p.setPen(SamplingPointColor);
- p.drawRects(sampling_points.data(), sampling_points.size());
- }
-}
-
-void AnalogSignal::paint_logic_caps(QPainter &p, QLineF *const lines,
- vector< pair<int64_t, bool> > &edges, bool level,
- double samples_per_pixel, double pixels_offset, float x_offset,
- float y_offset)
-{
- QLineF *line = lines;
-
- for (auto i = edges.begin(); i != (edges.end() - 1); i++)
- if ((*i).second == level) {
- *line++ = QLineF(
- ((*i).first / samples_per_pixel -
- pixels_offset) + x_offset, y_offset,
- ((*(i+1)).first / samples_per_pixel -
- pixels_offset) + x_offset, y_offset);
- }
-
- p.drawLines(lines, line - lines);
-}
-