LCOV - code coverage report
Current view: top level - muse/framework/draw/utils - drawdatacomp.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 72.4 % 225 163
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "drawdatacomp.h"
      23              : 
      24              : #include <list>
      25              : 
      26              : #include "global/realfn.h"
      27              : #include "global/containers.h"
      28              : 
      29              : #include "log.h"
      30              : 
      31              : using namespace muse::draw;
      32              : 
      33              : namespace muse::draw::comp {
      34              : static const int DEFAULT_PREC(3);
      35              : 
      36              : struct Polygon;
      37              : static bool isEqual(const Polygon& p1, const Polygon& p2, DrawDataComp::Tolerance tolerance);
      38              : 
      39              : struct Path {
      40              :     const DrawData::Item* obj = nullptr;
      41              :     const DrawData::Data* data = nullptr;
      42              :     const DrawPath* path = nullptr;
      43              : };
      44              : 
      45              : struct Polygon {
      46              :     const DrawData::Item* obj = nullptr;
      47              :     const DrawData::Data* data = nullptr;
      48              :     const DrawPolygon* polygon = nullptr;
      49              :     bool operator==(const Polygon& o) const { return isEqual(*this, o, DrawDataComp::Tolerance()); }
      50              : };
      51              : 
      52              : struct Text {
      53              :     const DrawData::Item* obj = nullptr;
      54              :     const DrawData::Data* data = nullptr;
      55              :     const DrawText* text = nullptr;
      56              : };
      57              : 
      58              : struct Pixmap {
      59              :     const DrawData::Item* obj = nullptr;
      60              :     const DrawData::Data* data = nullptr;
      61              :     const DrawPixmap* pixmap = nullptr;
      62              : };
      63              : 
      64              : struct Data {
      65              :     std::list<Path> paths;
      66              :     std::list<Polygon> polygons;
      67              :     std::list<Text> texts;
      68              :     std::list<Pixmap> pixmaps;
      69              : };
      70              : 
      71              : template<class T>
      72              : static bool isEqual(const std::vector<T>& v1, const std::vector<T>& v2, DrawDataComp::Tolerance tolerance);
      73              : 
      74          760 : static bool isEqual(const double& v1, const double& v2, double tolerance)
      75              : {
      76          760 :     if (tolerance > 0) {
      77            0 :         double delta = RealFloor(v1, DEFAULT_PREC) - RealFloor(v2, DEFAULT_PREC);
      78            0 :         return std::fabs(delta) < tolerance;
      79              :     }
      80          760 :     return RealIsEqual(RealFloor(v1, DEFAULT_PREC), RealFloor(v2, DEFAULT_PREC));
      81              : }
      82              : 
      83          288 : static bool isEqual(const PointF& p1, const PointF& p2, double tolerance)
      84              : {
      85          288 :     if (!isEqual(p1.x(), p2.x(), tolerance)) {
      86           56 :         return false;
      87              :     }
      88              : 
      89          232 :     if (!isEqual(p1.y(), p2.y(), tolerance)) {
      90          168 :         return false;
      91              :     }
      92              : 
      93           64 :     return true;
      94              : }
      95              : 
      96           54 : static bool isEqual(const RectF& r1, const RectF& r2, double tolerance)
      97              : {
      98           54 :     if (!isEqual(r1.x(), r2.x(), tolerance)) {
      99            0 :         return false;
     100              :     }
     101              : 
     102           54 :     if (!isEqual(r1.y(), r2.y(), tolerance)) {
     103            8 :         return false;
     104              :     }
     105              : 
     106           46 :     if (!isEqual(r1.width(), r2.width(), tolerance)) {
     107            0 :         return false;
     108              :     }
     109              : 
     110           46 :     if (!isEqual(r1.height(), r2.height(), tolerance)) {
     111            0 :         return false;
     112              :     }
     113              : 
     114           46 :     return true;
     115              : }
     116              : 
     117            0 : static bool isEqual(const Size& sz1, const Size& sz2)
     118              : {
     119            0 :     if (sz1.width() != sz2.width()) {
     120            0 :         return false;
     121              :     }
     122              : 
     123            0 :     if (sz1.height() != sz2.height()) {
     124            0 :         return false;
     125              :     }
     126              : 
     127            0 :     return true;
     128              : }
     129              : 
     130            4 : static bool isEqual(const Pen& p1, const Pen& p2)
     131              : {
     132            4 :     if (p1.style() != p2.style()) {
     133            0 :         return false;
     134              :     }
     135              : 
     136            4 :     if (!RealIsEqual(p1.widthF(), p2.widthF())) {
     137            0 :         return false;
     138              :     }
     139              : 
     140            4 :     if (p1.color() != p2.color()) {
     141            0 :         return false;
     142              :     }
     143              : 
     144            4 :     return true;
     145              : }
     146              : 
     147            4 : static bool isEqual(const Brush& b1, const Brush& b2)
     148              : {
     149            4 :     if (b1.style() != b2.style()) {
     150            0 :         return false;
     151              :     }
     152              : 
     153            4 :     if (b1.color() != b2.color()) {
     154            0 :         return false;
     155              :     }
     156              : 
     157            4 :     return true;
     158              : }
     159              : 
     160              : #if 0 // currently unused, disabled due to an MSVC compiler warning C4505
     161              : static bool isEqual(const Font& f1, const Font& f2)
     162              : {
     163              :     if (f1.family() != f2.family()) {
     164              :         return false;
     165              :     }
     166              : 
     167              :     if (!RealIsEqual(f1.pointSizeF(), f2.pointSizeF())) {
     168              :         return false;
     169              :     }
     170              : 
     171              :     if (f1.weight() != f2.weight()) {
     172              :         return false;
     173              :     }
     174              : 
     175              :     if (f1.italic() != f2.italic()) {
     176              :         return false;
     177              :     }
     178              : 
     179              :     return true;
     180              : }
     181              : 
     182              : static bool isEqual(const Transform& t1, const Transform& t2, double tolerance)
     183              : {
     184              :     if (!isEqual(t1.m11(), t2.m11(), tolerance)) {
     185              :         return false;
     186              :     }
     187              : 
     188              :     if (!isEqual(t1.m12(), t2.m12(), tolerance)) {
     189              :         return false;
     190              :     }
     191              : 
     192              :     if (!isEqual(t1.m13(), t2.m13(), tolerance)) {
     193              :         return false;
     194              :     }
     195              : 
     196              :     if (!isEqual(t1.m21(), t2.m21(), tolerance)) {
     197              :         return false;
     198              :     }
     199              : 
     200              :     if (!isEqual(t1.m22(), t2.m22(), tolerance)) {
     201              :         return false;
     202              :     }
     203              : 
     204              :     if (!isEqual(t1.m23(), t2.m23(), tolerance)) {
     205              :         return false;
     206              :     }
     207              : 
     208              :     if (!isEqual(t1.m31(), t2.m31(), tolerance)) {
     209              :         return false;
     210              :     }
     211              : 
     212              :     if (!isEqual(t1.m32(), t2.m32(), tolerance)) {
     213              :         return false;
     214              :     }
     215              : 
     216              :     if (!isEqual(t1.m33(), t2.m33(), tolerance)) {
     217              :         return false;
     218              :     }
     219              : 
     220              :     return true;
     221              : }
     222              : 
     223              : static bool isEqual(const DrawData::State& s1, const DrawData::State& s2, DrawDataComp::Tolerance tolerance)
     224              : {
     225              :     if (s1.isAntialiasing != s2.isAntialiasing) {
     226              :         return false;
     227              :     }
     228              : 
     229              :     if (s1.compositionMode != s2.compositionMode) {
     230              :         return false;
     231              :     }
     232              : 
     233              :     if (!isEqual(s1.pen, s2.pen)) {
     234              :         return false;
     235              :     }
     236              : 
     237              :     if (!isEqual(s1.brush, s2.brush)) {
     238              :         return false;
     239              :     }
     240              : 
     241              :     if (!isEqual(s1.font, s2.font)) {
     242              :         return false;
     243              :     }
     244              : 
     245              :     if (!isEqual(s1.transform, s2.transform, tolerance.base)) {
     246              :         return false;
     247              :     }
     248              : 
     249              :     return true;
     250              : }
     251              : 
     252              : #endif
     253              : 
     254            4 : static bool isEqual(const PainterPath& v1, const PainterPath& v2, double tolerance)
     255              : {
     256            4 :     if (v1.elementCount() != v2.elementCount()) {
     257            0 :         return false;
     258              :     }
     259              : 
     260           24 :     for (size_t i = 0; i < v1.elementCount(); ++i) {
     261           20 :         PainterPath::Element e1 = v1.elementAt(i);
     262           20 :         PainterPath::Element e2 = v2.elementAt(i);
     263              : 
     264           20 :         if (e1.type != e2.type) {
     265            0 :             return false;
     266              :         }
     267              : 
     268           20 :         if (!isEqual(e1.x, e2.x, tolerance)) {
     269            0 :             return false;
     270              :         }
     271              : 
     272           20 :         if (!isEqual(e1.y, e2.y, tolerance)) {
     273            0 :             return false;
     274              :         }
     275              :     }
     276              : 
     277            4 :     return true;
     278              : }
     279              : 
     280            4 : static bool isEqual(const DrawPath& v1, const DrawPath& v2, DrawDataComp::Tolerance tolerance)
     281              : {
     282            4 :     if (v1.mode != v2.mode) {
     283            0 :         return false;
     284              :     }
     285              : 
     286            4 :     if (!isEqual(v1.path, v2.path, tolerance.base)) {
     287            0 :         return false;
     288              :     }
     289              : 
     290            4 :     if (!isEqual(v1.pen, v2.pen)) {
     291            0 :         return false;
     292              :     }
     293              : 
     294            4 :     if (!isEqual(v1.brush, v2.brush)) {
     295            0 :         return false;
     296              :     }
     297              : 
     298            4 :     return true;
     299              : }
     300              : 
     301          234 : static bool isEqual(const PolygonF& v1, const PolygonF& v2, double tolerance)
     302              : {
     303          234 :     if (v1.size() != v2.size()) {
     304            0 :         return false;
     305              :     }
     306              : 
     307          298 :     for (size_t i = 0; i < v1.size(); ++i) {
     308          288 :         const PointF& p1 = v1.at(i);
     309          288 :         const PointF& p2 = v2.at(i);
     310              : 
     311          288 :         if (!isEqual(p1, p2, tolerance)) {
     312          224 :             return false;
     313              :         }
     314              :     }
     315              : 
     316           10 :     return true;
     317              : }
     318              : 
     319          234 : static bool isEqual(const DrawPolygon& v1, const DrawPolygon& v2, DrawDataComp::Tolerance tolerance)
     320              : {
     321          234 :     if (v1.mode != v2.mode) {
     322            0 :         return false;
     323              :     }
     324              : 
     325          234 :     if (!isEqual(v1.polygon, v2.polygon, tolerance.base)) {
     326          224 :         return false;
     327              :     }
     328              : 
     329           10 :     return true;
     330              : }
     331              : 
     332           54 : static bool isEqual(const DrawText& v1, const DrawText& v2, DrawDataComp::Tolerance tolerance)
     333              : {
     334           54 :     if (v1.mode != v2.mode) {
     335            0 :         return false;
     336              :     }
     337              : 
     338           54 :     if (!isEqual(v1.rect, v2.rect, tolerance.base)) {
     339            8 :         return false;
     340              :     }
     341              : 
     342           46 :     if (v1.alignment != v2.alignment) {
     343            0 :         return false;
     344              :     }
     345              : 
     346           46 :     if (v1.textFlags != v2.textFlags) {
     347            0 :         return false;
     348              :     }
     349              : 
     350           46 :     if (v1.text != v2.text) {
     351           34 :         return false;
     352              :     }
     353              : 
     354           12 :     return true;
     355              : }
     356              : 
     357            0 : static bool isEqual(const DrawPixmap& v1, const DrawPixmap& v2, DrawDataComp::Tolerance tolerance)
     358              : {
     359            0 :     if (v1.mode != v2.mode) {
     360            0 :         return false;
     361              :     }
     362              : 
     363            0 :     if (!isEqual(v1.rect, v2.rect, tolerance.base)) {
     364            0 :         return false;
     365              :     }
     366              : 
     367            0 :     if (!isEqual(v1.pm.size(), v2.pm.size())) {
     368            0 :         return false;
     369              :     }
     370              : 
     371            0 :     if (!isEqual(v1.offset, v2.offset, tolerance.base)) {
     372            0 :         return false;
     373              :     }
     374              : 
     375            0 :     return true;
     376              : }
     377              : 
     378              : #if 0 // currently unused, disabled due to an MSVC compiler warning C4505
     379              : static bool isEqual(const DrawData::Data& d1, const DrawData::Data& d2, DrawDataComp::Tolerance tolerance)
     380              : {
     381              :     if (!isEqual(d1.state, d2.state, tolerance)) {
     382              :         return false;
     383              :     }
     384              : 
     385              :     if (!isEqual(d1.paths, d2.paths, tolerance)) {
     386              :         return false;
     387              :     }
     388              : 
     389              :     if (!isEqual(d1.polygons, d2.polygons, tolerance)) {
     390              :         return false;
     391              :     }
     392              : 
     393              :     if (!isEqual(d1.texts, d2.texts, tolerance)) {
     394              :         return false;
     395              :     }
     396              : 
     397              :     if (!isEqual(d1.pixmaps, d2.pixmaps, tolerance)) {
     398              :         return false;
     399              :     }
     400              : 
     401              :     return true;
     402              : }
     403              : 
     404              : #endif
     405              : 
     406              : template<class T>
     407              : static bool isEqual(const std::vector<T>& v1, const std::vector<T>& v2, DrawDataComp::Tolerance tolerance)
     408              : {
     409              :     if (v1.size() != v2.size()) {
     410              :         return false;
     411              :     }
     412              : 
     413              :     for (size_t i = 0; i < v1.size(); ++i) {
     414              :         const T& vi1 = v1[i];
     415              :         const T& vi2 = v2[i];
     416              : 
     417              :         if (isEqual(vi1, vi2, tolerance)) {
     418              :             continue;
     419              :         } else {
     420              :             bool found = false;
     421              :             for (size_t j = 0; j < v2.size(); ++j) {
     422              :                 const T& vj2 = v2[j];
     423              : 
     424              :                 if (isEqual(vi1, vj2, tolerance)) {
     425              :                     found = true;
     426              :                     break;
     427              :                 }
     428              :             }
     429              : 
     430              :             if (!found) {
     431              :                 return false;
     432              :             }
     433              :         }
     434              :     }
     435              :     return true;
     436              : }
     437              : 
     438              : #if 0 // currently unused, disabled due to an MSVC compiler warning C4505
     439              : static bool isEqual(const DrawData::Object& o1, const DrawData::Object& o2, DrawDataComp::Tolerance tolerance)
     440              : {
     441              :     if (o1.name != o2.name) {
     442              :         return false;
     443              :     }
     444              : 
     445              :     if (!isEqual(o1.pagePos, o2.pagePos, tolerance.base)) {
     446              :         return false;
     447              :     }
     448              : 
     449              :     if (!isEqual(o1.datas, o2.datas, tolerance)) {
     450              :         return false;
     451              :     }
     452              : 
     453              :     return true;
     454              : }
     455              : 
     456              : #endif
     457              : 
     458            4 : static bool isEqual(const Path& p1, const Path& p2, DrawDataComp::Tolerance tolerance)
     459              : {
     460            4 :     if (p1.obj->name != p2.obj->name) {
     461            0 :         return false;
     462              :     }
     463              : 
     464            4 :     if (p1.data->state != p2.data->state) {
     465            0 :         return false;
     466              :     }
     467              : 
     468            4 :     return isEqual(*p1.path, *p2.path, tolerance);
     469              : }
     470              : 
     471         3378 : static bool isEqual(const Polygon& p1, const Polygon& p2, DrawDataComp::Tolerance tolerance)
     472              : {
     473         3378 :     if (p1.obj->name != p2.obj->name) {
     474            0 :         return false;
     475              :     }
     476              : 
     477         3378 :     if (p1.data->state != p2.data->state) {
     478         3144 :         return false;
     479              :     }
     480              : 
     481          234 :     return isEqual(*p1.polygon, *p2.polygon, tolerance);
     482              : }
     483              : 
     484         3802 : static bool isEqual(const Text& p1, const Text& p2, DrawDataComp::Tolerance tolerance)
     485              : {
     486         3802 :     if (p1.obj->name != p2.obj->name) {
     487            0 :         return false;
     488              :     }
     489              : 
     490         3802 :     if (p1.data->state != p2.data->state) {
     491         3748 :         return false;
     492              :     }
     493              : 
     494           54 :     return isEqual(*p1.text, *p2.text, tolerance);
     495              : }
     496              : 
     497            0 : static bool isEqual(const comp::Pixmap& p1, const comp::Pixmap& p2, DrawDataComp::Tolerance tolerance)
     498              : {
     499            0 :     if (p1.obj->name != p2.obj->name) {
     500            0 :         return false;
     501              :     }
     502              : 
     503            0 :     if (p1.data->state != p2.data->state) {
     504            0 :         return false;
     505              :     }
     506              : 
     507            0 :     return isEqual(*p1.pixmap, *p2.pixmap, tolerance);
     508              : }
     509              : 
     510              : template<class T>
     511              : static bool contains(const std::vector<T>& v1, const T& val, DrawDataComp::Tolerance tolerance)
     512              : {
     513              :     for (size_t i = 0; i < v1.size(); ++i) {
     514              :         const T& t = v1.at(i);
     515              :         if (isEqual(t, val, tolerance)) {
     516              :             return true;
     517              :         }
     518              :     }
     519              :     return false;
     520              : }
     521              : 
     522              : template<class T>
     523              : static void difference(std::vector<T>& diff, const std::vector<T>& v1, const std::vector<T>& v2, DrawDataComp::Tolerance tolerance)
     524              : {
     525              :     for (size_t i = 0; i < v1.size(); ++i) {
     526              :         const T& t = v1.at(i);
     527              :         if (!contains(v2, t, tolerance)) {
     528              :             diff.push_back(t);
     529              :         }
     530              :     }
     531              : }
     532              : 
     533              : template<class T>
     534          186 : static bool contains(const std::list<T>& v1, const T& val, DrawDataComp::Tolerance tolerance)
     535              : {
     536         7344 :     for (const T& t : v1) {
     537         7184 :         if (isEqual(t, val, tolerance)) {
     538           26 :             return true;
     539              :         }
     540              :     }
     541          160 :     return false;
     542              : }
     543              : 
     544              : template<class T>
     545           16 : static void difference(std::list<T>& diff, const std::list<T>& v1, const std::list<T>& v2, DrawDataComp::Tolerance tolerance)
     546              : {
     547          202 :     for (const T& t : v1) {
     548          186 :         if (!contains(v2, t, tolerance)) {
     549          160 :             diff.push_back(t);
     550              :         }
     551              :     }
     552           16 : }
     553              : 
     554            4 : static void difference(Data& diff, const Data& d1, const Data& d2, DrawDataComp::Tolerance tolerance)
     555              : {
     556            4 :     difference(diff.paths, d1.paths, d2.paths, tolerance);
     557            4 :     difference(diff.polygons, d1.polygons, d2.polygons, tolerance);
     558            4 :     difference(diff.texts, d1.texts, d2.texts, tolerance);
     559            4 :     difference(diff.pixmaps, d1.pixmaps, d2.pixmaps, tolerance);
     560            4 : }
     561              : 
     562            6 : static void toCompData(Data& cd, const DrawData::Item& item)
     563              : {
     564          158 :     for (const DrawData::Data& d : item.datas) {
     565          156 :         for (const DrawPath& p : d.paths) {
     566            4 :             cd.paths.push_back(comp::Path { &item, &d, &p });
     567              :         }
     568          242 :         for (const DrawPolygon& p : d.polygons) {
     569           90 :             cd.polygons.push_back(comp::Polygon { &item, &d, &p });
     570              :         }
     571          244 :         for (const DrawText& p : d.texts) {
     572           92 :             cd.texts.push_back(comp::Text { &item, &d, &p });
     573              :         }
     574          152 :         for (const DrawPixmap& p : d.pixmaps) {
     575            0 :             cd.pixmaps.push_back(comp::Pixmap { &item, &d, &p });
     576              :         }
     577              :     }
     578              : 
     579            8 :     for (const DrawData::Item& ch : item.chilren) {
     580            2 :         toCompData(cd, ch);
     581              :     }
     582            6 : }
     583              : 
     584            4 : static Data toCompData(const DrawDataPtr& dd)
     585              : {
     586            4 :     Data cd;
     587            4 :     toCompData(cd, dd->item);
     588            4 :     return cd;
     589            0 : }
     590              : 
     591            4 : static void fillDrawData(DrawDataPtr& dd, const comp::Data& cd)
     592              : {
     593              :     //! NOTE Not effective, but efficiency is not required yet
     594              : 
     595              :     // collect objects (save order)
     596            4 :     std::vector<const DrawData::Item*> objs;
     597            4 :     for (const comp::Path& p : cd.paths) {
     598            0 :         if (!muse::contains(objs, p.obj)) {
     599            0 :             objs.push_back(p.obj);
     600              :         }
     601              :     }
     602           84 :     for (const comp::Polygon& p : cd.polygons) {
     603           80 :         if (!muse::contains(objs, p.obj)) {
     604            4 :             objs.push_back(p.obj);
     605              :         }
     606              :     }
     607           84 :     for (const comp::Text& p : cd.texts) {
     608           80 :         if (!muse::contains(objs, p.obj)) {
     609            0 :             objs.push_back(p.obj);
     610              :         }
     611              :     }
     612            4 :     for (const comp::Pixmap& p : cd.pixmaps) {
     613            0 :         if (!muse::contains(objs, p.obj)) {
     614            0 :             objs.push_back(p.obj);
     615              :         }
     616              :     }
     617              : 
     618              :     // collect data
     619            8 :     for (const DrawData::Item* o : objs) {
     620            4 :         DrawData::Item dobj;
     621            4 :         dobj.name = o->name;
     622              : 
     623          160 :         auto findOrCreateDData = [](DrawData::Item& dobj, int state) {
     624          160 :             DrawData::Data* ddata = nullptr;
     625              : 
     626              :             // find by state
     627         4374 :             for (DrawData::Data& od : dobj.datas) {
     628         4214 :                 if (od.state == state) {
     629           32 :                     ddata = &od;
     630              :                 }
     631              :             }
     632              : 
     633              :             // add new, if not find
     634          160 :             if (!ddata) {
     635          128 :                 dobj.datas.push_back(DrawData::Data());
     636          128 :                 ddata = &dobj.datas.back();
     637          128 :                 ddata->state = state;
     638              :             }
     639              : 
     640          160 :             return ddata;
     641              :         };
     642              : 
     643            4 :         for (const comp::Path& p : cd.paths) {
     644            0 :             DrawData::Data* ddata = findOrCreateDData(dobj, p.data->state);
     645            0 :             ddata->paths.push_back(*p.path);
     646              :         }
     647              : 
     648           84 :         for (const comp::Polygon& p : cd.polygons) {
     649           80 :             DrawData::Data* ddata = findOrCreateDData(dobj, p.data->state);
     650           80 :             ddata->polygons.push_back(*p.polygon);
     651              :         }
     652              : 
     653           84 :         for (const comp::Text& p : cd.texts) {
     654           80 :             DrawData::Data* ddata = findOrCreateDData(dobj, p.data->state);
     655           80 :             ddata->texts.push_back(*p.text);
     656              :         }
     657              : 
     658            4 :         for (const comp::Pixmap& p : cd.pixmaps) {
     659            0 :             DrawData::Data* ddata = findOrCreateDData(dobj, p.data->state);
     660            0 :             ddata->pixmaps.push_back(*p.pixmap);
     661              :         }
     662              : 
     663            4 :         dd->item.chilren.push_back(dobj);
     664            4 :     }
     665            4 : }
     666              : } // muse::draw::comp
     667              : 
     668            2 : Diff DrawDataComp::compare(const DrawDataPtr& data, const DrawDataPtr& origin, Tolerance tolerance)
     669              : {
     670            2 :     Diff diff;
     671            2 :     IF_ASSERT_FAILED(data) {
     672            0 :         return diff;
     673              :     }
     674              : 
     675            2 :     IF_ASSERT_FAILED(origin) {
     676            0 :         return diff;
     677              :     }
     678              : 
     679            2 :     comp::Data cdata = comp::toCompData(data);
     680            2 :     comp::Data corigin = comp::toCompData(origin);
     681              : 
     682            2 :     comp::Data added;
     683            2 :     comp::difference(added, corigin, cdata, tolerance);
     684              : 
     685            2 :     comp::Data removed;
     686            2 :     comp::difference(removed, cdata, corigin, tolerance);
     687              : 
     688            2 :     diff.dataAdded = std::make_shared<DrawData>();
     689            2 :     diff.dataAdded->name = origin->name;
     690            2 :     diff.dataAdded->viewport = origin->viewport;
     691            2 :     diff.dataAdded->states = origin->states;
     692            2 :     fillDrawData(diff.dataAdded, added);
     693              : 
     694            2 :     diff.dataRemoved = std::make_shared<DrawData>();
     695            2 :     diff.dataRemoved->name = origin->name;
     696            2 :     diff.dataRemoved->viewport = origin->viewport;
     697            2 :     diff.dataRemoved->states = origin->states;
     698            2 :     fillDrawData(diff.dataRemoved, removed);
     699              : 
     700            2 :     return diff;
     701            2 : }
        

Generated by: LCOV version 2.0-1