Verovio
Source code documentation
comparison.h
1 // Name: comparison.h
3 // Author: Laurent Pugin
4 // Created: 2015
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_COMPARISON_H__
9 #define __VRV_COMPARISON_H__
10 
11 #include "artic.h"
12 #include "atts_shared.h"
13 #include "durationinterface.h"
14 #include "horizontalaligner.h"
15 #include "lyricelement.h"
16 #include "measure.h"
17 #include "note.h"
18 #include "object.h"
19 #include "staffdef.h"
20 #include "staffgrp.h"
21 #include "symbol.h"
22 #include "timeinterface.h"
23 
24 namespace vrv {
25 
26 enum DurExtreme { LONGEST = 0, SHORTEST };
27 
28 //----------------------------------------------------------------------------
29 // Comparison
30 //----------------------------------------------------------------------------
31 
32 class Comparison {
33 
34 public:
35  virtual bool operator()(const Object *object) = 0;
36  // For classes that do a reverse comparison, return reversed result
37  bool Result(bool comparison) { return (m_reverse) ? !comparison : comparison; }
38  // Set reverse comparison.
39  // This is possible only for Comparison classes that allow it explicitly
40  void ReverseComparison()
41  {
42  assert(m_supportReverse);
43  m_reverse = true;
44  }
45 
46 protected:
47  // This is set to true in contructor of classes that allow it
48  bool m_supportReverse = false;
49 
50 private:
51  // The flag indicating if a reverse comparison needs to be done
52  bool m_reverse = false;
53 };
54 
55 //----------------------------------------------------------------------------
56 // ClassIdComparison
57 //----------------------------------------------------------------------------
58 
59 class ClassIdComparison : public Comparison {
60 
61 public:
62  ClassIdComparison(ClassId classId)
63  {
64  m_classId = classId;
65  m_supportReverse = true;
66  }
67 
68  bool operator()(const Object *object) override { return Result(this->MatchesType(object)); }
69 
70  ClassId GetType() { return m_classId; }
71 
72  bool MatchesType(const Object *object) { return (object->Is(m_classId)); }
73 
74 protected:
75  ClassId m_classId;
76 };
77 
78 //----------------------------------------------------------------------------
79 // ClassIdsComparison
80 //----------------------------------------------------------------------------
81 
83 
84 public:
85  ClassIdsComparison(const std::vector<ClassId> &classIds)
86  {
87  m_classIds = classIds;
88  m_supportReverse = true;
89  }
90 
91  bool operator()(const Object *object) override { return Result(this->MatchesType(object)); }
92 
93  bool MatchesType(const Object *object) { return (object->IsAnyOf(m_classIds)); }
94 
95 protected:
96  std::vector<ClassId> m_classIds;
97 };
98 
99 //----------------------------------------------------------------------------
100 // InterfaceComparison
101 //----------------------------------------------------------------------------
102 
104 
105 public:
106  InterfaceComparison(InterfaceId interfaceId) { m_interfaceId = interfaceId; }
107 
108  bool operator()(const Object *object) override
109  {
110  if (object->HasInterface(m_interfaceId)) {
111  return true;
112  }
113  return false;
114  }
115 
116 protected:
117  InterfaceId m_interfaceId;
118 };
119 
120 //----------------------------------------------------------------------------
121 // ChildOfClassIdComparison
122 //----------------------------------------------------------------------------
123 
125 
126 public:
127  ChildOfClassIdComparison(ClassId classId) { m_classId = classId; }
128 
129  bool operator()(const Object *object) override
130  {
131  return (object->GetParent() && object->GetParent()->GetClassId() == m_classId);
132  }
133 
134 protected:
135  ClassId m_classId;
136 };
137 
138 //----------------------------------------------------------------------------
139 // PointingToComparison
140 //----------------------------------------------------------------------------
141 
143 
144 public:
145  PointingToComparison(ClassId classId, const Object *pointingTo) : ClassIdComparison(classId)
146  {
147  m_pointingTo = pointingTo;
148  }
149 
150  bool operator()(const Object *object) override
151  {
152  if (!MatchesType(object)) return false;
153  const TimePointInterface *interface = object->GetTimePointInterface();
154  if (!interface) return false;
155  return (interface->GetStart() == m_pointingTo);
156  }
157 
158 protected:
159  const Object *m_pointingTo;
160 };
161 
162 //----------------------------------------------------------------------------
163 // SpanningToComparison
164 //----------------------------------------------------------------------------
165 
167 
168 public:
169  SpanningToComparison(ClassId classId, const Object *pointingTo) : ClassIdComparison(classId)
170  {
171  m_pointingTo = pointingTo;
172  }
173 
174  bool operator()(const Object *object) override
175  {
176  if (!MatchesType(object)) return false;
177  const TimeSpanningInterface *interface = object->GetTimeSpanningInterface();
178  if (!interface) return false;
179  return (interface->GetEnd() == m_pointingTo);
180  }
181 
182 protected:
183  const Object *m_pointingTo;
184 };
185 
186 //----------------------------------------------------------------------------
187 // IsEditorialElementComparison
188 //----------------------------------------------------------------------------
189 
194 
195 public:
196  IsEditorialElementComparison() : Comparison() { m_supportReverse = true; }
197 
198  bool operator()(const Object *object) override
199  {
200  if (object->IsEditorialElement()) return Result(true);
201  return Result(false);
202  }
203 };
204 
205 //----------------------------------------------------------------------------
206 // IsEmptyComparison
207 //----------------------------------------------------------------------------
208 
213 
214 public:
215  IsEmptyComparison(ClassId classId) : ClassIdComparison(classId) { m_supportReverse = true; }
216 
217  bool operator()(const Object *object) override
218  {
219  if (!MatchesType(object)) return false;
220  if (object->GetChildCount() == 0) {
221  return Result(true);
222  }
223  else {
224  return Result(false);
225  }
226  }
227 };
228 
229 //----------------------------------------------------------------------------
230 // IsAttributeComparison
231 //----------------------------------------------------------------------------
232 
237 
238 public:
239  IsAttributeComparison(ClassId classId) : ClassIdComparison(classId) {}
240 
241  bool operator()(const Object *object) override
242  {
243  if (!MatchesType(object)) return false;
244  if (object->IsAttribute()) return true;
245  return false;
246  }
247 };
248 
249 //----------------------------------------------------------------------------
250 // AttNIntegerComparison
251 //----------------------------------------------------------------------------
252 
257 
258 public:
259  AttNIntegerComparison(ClassId classId, const int n) : ClassIdComparison(classId) { m_n = n; }
260 
261  void SetN(int n) { m_n = n; }
262 
263  bool operator()(const Object *object) override
264  {
265  if (!MatchesType(object)) return false;
266  // This should not happen, but just in case
267  if (!object->HasAttClass(ATT_NINTEGER)) return false;
268  const AttNInteger *element = dynamic_cast<const AttNInteger *>(object);
269  assert(element);
270  return (element->GetN() == m_n);
271  }
272 
273 private:
274  int m_n;
275 };
276 
277 //----------------------------------------------------------------------------
278 // AttNIntegerAnyComparison
279 //----------------------------------------------------------------------------
280 
285 
286 public:
287  AttNIntegerAnyComparison(ClassId classId, std::vector<int> ns) : ClassIdComparison(classId) { m_ns = ns; }
288 
289  void SetNs(std::vector<int> ns) { m_ns = ns; }
290  void AppendN(int n) { m_ns.push_back(n); }
291 
292  bool operator()(const Object *object) override
293  {
294  if (!MatchesType(object)) return false;
295  // This should not happen, but just in case
296  if (!object->HasAttClass(ATT_NINTEGER)) return false;
297  const AttNInteger *element = dynamic_cast<const AttNInteger *>(object);
298  assert(element);
299  return (std::find(m_ns.begin(), m_ns.end(), element->GetN()) != m_ns.end());
300  }
301 
302 private:
303  std::vector<int> m_ns;
304 };
305 
306 //----------------------------------------------------------------------------
307 // LyricElementComparison
308 //----------------------------------------------------------------------------
309 
312 public:
313  LyricElementComparison(ClassId classId, int groupN) : ClassIdComparison(classId), m_groupN(groupN)
314  {
315  assert(Object::IsLyricElement(classId));
316  }
317 
318  bool operator()(const Object *object) override
319  {
320  if (!this->MatchesType(object)) return false;
321  const LyricElement *lyricElement = vrv_cast<const LyricElement *>(object);
322  assert(lyricElement);
323  return (lyricElement->GetDrawingLyricGroupN() == m_groupN);
324  }
325 
326 private:
327  int m_groupN;
328 };
329 
330 //----------------------------------------------------------------------------
331 // AttNNumberLikeComparison
332 //----------------------------------------------------------------------------
333 
338 
339 public:
340  AttNNumberLikeComparison(ClassId classId, const std::string n) : ClassIdComparison(classId) { m_n = n; }
341 
342  void SetN(std::string n) { m_n = n; }
343 
344  bool operator()(const Object *object) override
345  {
346  if (!MatchesType(object)) return false;
347  // This should not happen, but just in case
348  if (!object->HasAttClass(ATT_NNUMBERLIKE)) return false;
349  const AttNNumberLike *element = dynamic_cast<const AttNNumberLike *>(object);
350  assert(element);
351  return (element->GetN() == m_n);
352  }
353 
354 private:
355  std::string m_n;
356 };
357 
358 //----------------------------------------------------------------------------
359 // AttDurExtremeComparison
360 //----------------------------------------------------------------------------
361 
368 
369 public:
370  AttDurExtremeComparison(DurExtreme extremeType) : ClassIdComparison(OBJECT)
371  {
372  m_extremeType = extremeType;
373  m_extremeDur = (m_extremeType == LONGEST) ? -VRV_UNSET : VRV_UNSET;
374  }
375 
376  bool operator()(const Object *object) override
377  {
378  if (!object->HasInterface(INTERFACE_DURATION)) return false;
379  const DurationInterface *interface = dynamic_cast<const DurationInterface *>(object);
380  assert(interface);
381  if (interface->HasDur()) {
382  if ((m_extremeType == LONGEST) && (interface->GetActualDur() < m_extremeDur)) {
383  m_extremeDur = interface->GetActualDur();
384  return true;
385  }
386  else if ((m_extremeType == SHORTEST) && (interface->GetActualDur() > m_extremeDur)) {
387  m_extremeDur = interface->GetActualDur();
388  return true;
389  }
390  }
391  return false;
392  }
393 
394 private:
395  int m_extremeDur;
396  DurExtreme m_extremeType;
397 };
398 
399 //----------------------------------------------------------------------------
400 // AttVisibilityComparison
401 //----------------------------------------------------------------------------
406 
407 public:
408  AttVisibilityComparison(ClassId classId, data_BOOLEAN isVisible) : ClassIdComparison(classId)
409  {
410  m_isVisible = isVisible;
411  };
412 
413  bool operator()(const Object *object) override
414  {
415  if (!MatchesType(object)) return false;
416  if (!object->HasAttClass(ATT_VISIBILITY)) return false;
417  const AttVisibility *visibility = dynamic_cast<const AttVisibility *>(object);
418  assert(visibility);
419  return (visibility->GetVisible() == m_isVisible);
420  }
421 
422 private:
423  data_BOOLEAN m_isVisible;
424 };
425 
426 //----------------------------------------------------------------------------
427 // AttFormeworkComparison
428 //----------------------------------------------------------------------------
429 
434 
435 public:
436  AttFormeworkComparison(ClassId classId, data_PGFUNC func) : ClassIdComparison(classId) { m_func = func; }
437 
438  bool operator()(const Object *object) override
439  {
440  if (!MatchesType(object)) return false;
441  // This should not happen, but just in case
442  if (!object->HasAttClass(ATT_FORMEWORK)) return false;
443  const AttFormework *element = dynamic_cast<const AttFormework *>(object);
444  assert(element);
445  return (element->GetFunc() == m_func);
446  }
447 
448 private:
449  data_PGFUNC m_func;
450 };
451 
452 //----------------------------------------------------------------------------
453 // CrossAlignmentReferenceComparison
454 //----------------------------------------------------------------------------
455 
460 public:
461  CrossAlignmentReferenceComparison() : ClassIdComparison(ALIGNMENT_REFERENCE) {}
462 
463  bool operator()(const Object *object) override
464  {
465  if (!this->MatchesType(object)) return false;
466  const AlignmentReference *ref = vrv_cast<const AlignmentReference *>(object);
467  assert(ref);
468  return ref->HasCrossStaffElements();
469  }
470 };
471 
472 //----------------------------------------------------------------------------
473 // MeasureAlignerTypeComparison
474 //----------------------------------------------------------------------------
475 
480 
481 public:
482  MeasureAlignerTypeComparison(const AlignmentType type) : ClassIdComparison(ALIGNMENT) { m_type = type; }
483 
484  void SetType(AlignmentType type) { m_type = type; }
485 
486  bool operator()(const Object *object) override
487  {
488  if (!MatchesType(object)) return false;
489  const Alignment *alignment = vrv_cast<const Alignment *>(object);
490  assert(alignment);
491  return (alignment->GetType() == m_type);
492  }
493 
494 private:
495  AlignmentType m_type;
496 };
497 
498 //----------------------------------------------------------------------------
499 // MeasureOnsetOffsetComparison
500 //----------------------------------------------------------------------------
501 
506 
507 public:
508  MeasureOnsetOffsetComparison(const int time) : ClassIdComparison(MEASURE) { m_time = time; }
509 
510  void SetTime(int time) { m_time = time; }
511 
512  bool operator()(const Object *object) override
513  {
514  if (!MatchesType(object)) return false;
515  const Measure *measure = vrv_cast<const Measure *>(object);
516  assert(measure);
517  return (measure->EnclosesTime(m_time) != VRV_UNSET);
518  }
519 
520 private:
521  int m_time;
522 };
523 
524 //----------------------------------------------------------------------------
525 // NoteOrRestOnsetOffsetComparison
526 //----------------------------------------------------------------------------
527 
532 
533 public:
534  NoteOrRestOnsetOffsetComparison(const int time) : ClassIdsComparison({ NOTE, REST }) { m_time = time; }
535 
536  void SetTime(int time) { m_time = time; }
537 
538  bool operator()(const Object *object) override
539  {
540  if (!MatchesType(object)) return false;
541  const DurationInterface *interface = object->GetDurationInterface();
542  assert(interface);
543  return ((m_time >= interface->GetRealTimeOnsetMilliseconds())
544  && (m_time <= interface->GetRealTimeOffsetMilliseconds()));
545  }
546 
547 private:
548  int m_time;
549 };
550 
551 //----------------------------------------------------------------------------
552 // IDComparison
553 //----------------------------------------------------------------------------
554 
559 
560 public:
561  IDComparison(ClassId classId, const std::string &id) : ClassIdComparison(classId) { m_id = id; }
562 
563  void SetID(const std::string &id) { m_id = id; }
564 
565  bool operator()(const Object *object) override
566  {
567  if (!MatchesType(object)) return false;
568  return (object->GetID() == m_id);
569  }
570 
571 private:
572  std::string m_id;
573 };
574 
575 //----------------------------------------------------------------------------
576 // VisibleStaffDefOrGrpObject
577 //----------------------------------------------------------------------------
583 
584 public:
585  VisibleStaffDefOrGrpObject() : ClassIdsComparison({ STAFFDEF, STAFFGRP }) {}
586 
587  void Skip(const Object *objectToExclude) { m_objectToExclude = objectToExclude; }
588 
589  bool operator()(const Object *object) override
590  {
591  if (object == m_objectToExclude || !ClassIdsComparison::operator()(object)) return false;
592 
593  if (object->Is(STAFFDEF)) {
594  const StaffDef *staffDef = vrv_cast<const StaffDef *>(object);
595  return staffDef && staffDef->GetDrawingVisibility() != OPTIMIZATION_HIDDEN;
596  }
597 
598  const StaffGrp *staffGrp = vrv_cast<const StaffGrp *>(object);
599  return staffGrp && staffGrp->GetDrawingVisibility() != OPTIMIZATION_HIDDEN;
600  }
601 
602 protected:
603  const Object *m_objectToExclude;
604 };
605 
606 //----------------------------------------------------------------------------
607 // Filters class
608 //----------------------------------------------------------------------------
609 
613 class Filters {
614 public:
615  enum class Type { AllOf, AnyOf };
616 
617 public:
618  Filters() = default;
619  explicit Filters(const std::initializer_list<Comparison *> &comp)
620  {
621  std::copy(comp.begin(), comp.end(), std::back_inserter(m_filters));
622  }
623 
624  void Add(Comparison *comp) { m_filters.push_back(comp); }
625  void Clear() { m_filters.clear(); }
626  void SetType(Type type) { m_type = type; }
627 
631  bool Apply(const Object *object) const
632  {
633  auto condition = [object](Comparison *iter) {
634  // ignore any class comparison which does not match the object class
635  ClassIdComparison *cmp = dynamic_cast<ClassIdComparison *>(iter);
636  if (cmp) return (cmp->GetType() != object->GetClassId()) ? true : (*iter)(object);
637  return (*iter)(object);
638  };
639  switch (m_type) {
640  case Type::AnyOf: {
641  return std::any_of(m_filters.cbegin(), m_filters.cend(), condition);
642  }
643  case Type::AllOf:
644  default: {
645  return std::all_of(m_filters.cbegin(), m_filters.cend(), condition);
646  }
647  }
648  }
649 
650  Filters &operator=(const std::initializer_list<Comparison *> &other)
651  {
652  m_filters.clear();
653  std::copy(other.begin(), other.end(), std::back_inserter(m_filters));
654  return *this;
655  }
656 
657 private:
658  std::vector<Comparison *> m_filters;
659  Type m_type = Type::AllOf;
660 };
661 
662 } // namespace vrv
663 
664 #endif
Definition: add.h:20
This class stores an alignment position elements will point to.
Definition: horizontalaligner.h:77
This class stores a references of LayerElements for a staff.
Definition: horizontalaligner.h:294
bool HasCrossStaffElements() const
Return true if the reference has elements from cross-staff.
This class evaluates if the object the extreme duration so far The object has to have a DurationInter...
Definition: comparison.h:367
This class evaluates if the object is of a certain ClassId and has a @func of value func.
Definition: comparison.h:433
This class evaluates if the object is of a certain ClassId and has a of value n.
Definition: comparison.h:284
This class evaluates if the object is of a certain ClassId and has a of value n.
Definition: comparison.h:256
This class evaluates if the object is of a certain ClassId and has a of value n.
Definition: comparison.h:337
This class evaluates if the object is visible.
Definition: comparison.h:405
Definition: comparison.h:124
Definition: comparison.h:59
Definition: comparison.h:82
Definition: comparison.h:32
This class evaluates if alignment reference contains cross-staff elements.
Definition: comparison.h:459
This class is an interface for elements with duration, such as notes and rests.
Definition: durationinterface.h:39
This class is used to store comparison filters and apply them when necessary.
Definition: comparison.h:613
bool Apply(const Object *object) const
Apply comparison filter based on the specified type.
Definition: comparison.h:631
This class evaluates if the object is of a certain ClassId has a certain ID.
Definition: comparison.h:558
Definition: comparison.h:103
This class evaluates if the object is of a certain ClassId and is an attribute in the original MEI.
Definition: comparison.h:236
This class evaluates if the object is an editorial element.
Definition: comparison.h:193
This class evaluates if the object is of a certain ClassId and is empty.
Definition: comparison.h:212
Match a verse or refrain by its internal lyric-processing group.
Definition: comparison.h:311
Shared implementation for note-attached verse and refrain lyrics.
Definition: lyricelement.h:33
int GetDrawingLyricGroupN() const
Stable processing group used to isolate connectors and horizontal spacing.
Definition: lyricelement.h:63
This class evaluates if the object is an Alignment of a certain type.
Definition: comparison.h:479
This class represents a measure in a page-based score (Doc).
Definition: measure.h:46
int EnclosesTime(int time) const
Check if the measure encloses the given time (in millisecond) Return the playing repeat time (1-based...
This class evaluates if the object is a measure enclosing the given time.
Definition: comparison.h:505
This class evaluates if the object is a note being played at the given time.
Definition: comparison.h:531
This class represents a basic object.
Definition: object.h:66
Object * GetParent()
Get the parent of the Object.
Definition: object.h:410
Definition: comparison.h:142
Definition: comparison.h:166
This class represents a MEI staffDef.
Definition: staffdef.h:37
This class represents a MEI staffGrp.
Definition: staffgrp.h:39
This class is an interface for elements having a single time point, such as tempo,...
Definition: timeinterface.h:39
This class is an interface for spanning elements, such as slur, hairpin, etc.
Definition: timeinterface.h:145
This class evaluates if the object is a visible StaffDef or StaffGrp.
Definition: comparison.h:582