-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Qt toolkit #693
Add Qt toolkit #693
Conversation
- Source of Bravura-1.204.otf: https://www.smufl.org/files/bravura-1.204.zip - Source of Leipzig-5.2.ttf: Converted from Leipzig-5.2.sfd with https://everythingfonts.com/sfd-to-ttf License: Both fonts are licensed under the SIL Open Font License.
Thanks for this, it looks pretty good! Could you fill the CLA https://github.com/rism-ch/verovio/blob/master/doc/contributing.md ? |
I just sent the CLA to info@rism-ch.org |
Thanks. I can compile both the library and the demo but the demo crashes on
Any clue? |
qt/lib/qtscenegraphdevicecontext.h
Outdated
#define __QTSCENEGRAPHDEVICECONTEXT_H__ | ||
|
||
//---------------------------------------------------------------------------- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to include <cmath>
for this file to compile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added <cmath>
to the .cpp file which uses std::sin etc. I couldn't find anything in the .h file that might require .
Which version of Qt are you using? I mainly tried it with 5.9.1, and did a bit of testing with 5.8.0. |
I am using 5.9.1. Commenting avoiding it to crash. I now shows an empty window. Do I need to pass a file as parameter? |
The last commit fixes some issues with the multisample antialiasing, especially on macOS where some things have to be done at an earlier stage. |
That looks familiar... I had the same problem when running the demo on Android. The problem is that the point size is given in pixels which I try to convert to point size for having higher accuracy. But as this seems to be platform-dependent, I've changed it back to pixel size for now. A better solution would be if Verovio could use point size throughout. This would also make more sense because the functions in FontInfo are called GetPointSize(). |
…urce path and file content.
I get this after compiling: I am using MacOS 10.12.5 and Qt 5.9.1. The application is 80 KB, are the dynamic libraries and/or the verovio fonts also supposed to be include in it? The application error was that the dynamic library verovio-qt.1.dylib was not found: I had compiled it in Can the libraries be included in the application and/or compiled statically into the app executable? Where will the fonts be accessed? It would also probably be useful to include in the app rather relying on the system installation since there could be different versions of verovio associated with different compiled apps. |
/** | ||
* This class represents one Verovio document. | ||
*/ | ||
class VerovioDoc : public QObject { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this class is a wrapper around the Verovio toolkit I would not call it VerovioDoc but instead something like QtVrvToolkit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that makes sense. Instead of using a namespace in the class name (QtVrvToolkit) I've decided to put all classes of verovio-qt in its own namespace vrv_qt
. I first thought about using a nested namespace (vrv::qt
) but that leads to indenting everying inside of that namespace by the used clang-format.
The file has been renamed to verovioqttoolkit.h/cpp. I would have preferred to just name it toolkit.h/cpp but that's not possible because the Verovio library requires include/vrv to be in the INCLUDEPATH and thus pollutes the .
include path.
void setFileName(QString fileName); | ||
void setFileContent(QString fileContent); | ||
void setMusicFont(QString musicFont); | ||
void setPageWidth(int pageWidth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not having one single method for a this, namely setOptions that takes a JSON string an pass it to the vrv::toolkit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These setters are directly used by the Q_PROPERTY definition which exposes the fields as QML attributes. If using a JSON string instead, constructing the required options from QML would be a lot more cumbersome.
See: http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html
|
||
private: | ||
// configuration parameters for Verovio | ||
int m_pageWidth; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With setOptions passed to the toolkit I think you would not need to have all these members duplicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea. Even without using a JSON string all function calls can be directly delegated to the corresponding function in vrv::Toolkit.
One exception is the pageWidth and pageHeight which actually have a different meaning in verovio-qt, because they take into account the current scale. Thus I renamed them to displayWidth and displayHeight.
/** | ||
* This class represents one page of a Verovio document. | ||
*/ | ||
class VerovioPage : public QQuickItem { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about the name either. It creates confusion with vrv::Page. It looks more like a View to me. So maybe QtVrvView?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got confused by view_page and page, so yet this class actually represents a vrv::View. Thus I renamed it to vrv_qt::View.
tools/CMakeLists.txt
Outdated
${verovio_SRC} | ||
${hum_SRC} | ||
${midi_SRC} | ||
../src/pugi/pugixml.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have too much code duplication here. We need to find a way to have the list of common source files in a variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed that!
In addition I've added a new custom target for the header files. That is required for QtCreator, otherwise all .h files are not shown in the project tree. The custom target should not have any consequences to other IDEs.
We need the demo to be the most basic possible example. Just loading a file and displaying it. The current demo is great but should sit somewhere else, maybe in another repository. We need to add a note for the license compliance to make it clear that this can be used only with the LGPL version of Qt (and not the commercial license). Finally, we will not be able to maintain this at the RISM-CH and will have to rely on the community. |
@craigsapp: If you compile and run the demo with QtCreator, it takes care of setting the library path. Just make sure that in the project settings -> Run, the option "Add library path to LD_LIBRARY_PATH" (or similar) is enabled. If you want to run the demo without QtCreator you have to specify the library path yourself. On Mac you can use DYLD_LIBRARY_PATH for this. As I don't have a Mac I can't tell you the exact commands, but maybe @lpugin can help with this. For reference, on Linux, starting the verovio-qt-demo works with the following command:
This has to be executed in the directory of the verovio-qt-demo. ../../build specifies the directory with libverovio.so and ../build the directory with libverovio-qt.so. Alternatively copying the two libraries to the directory of verovio-qt-demo and starting it as follows also works:
Using static libraries would of course also work, but as Verovio is licensed under LGPL, using dynamic linking should be the more popular case. In my commit, just before your comment, I've added the QML properties resourcesDataPath and fontDirPath that can be used to specify the font-related directories. |
- Strip down verovio-qt-demo - Rename classes - Remove configuration class members from vrv_qt::Toolkit - Improve Verovio's CMakeLists.txt
@lpugin: Thank you very much for your valuable feedback. I've stripped down the verovio-qt-demo a lot and considered your feedback with my latest commit. Regarding the commercial Qt license: I am not a lawyer, but to my understanding the license of Qt does not matter as long as verovio and verovio-qt are included as shared libraries and thus allow it to be replaced by another version of that library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the previous changes. A few more requests here. Also, changing the font to Leipzig or Gootville does not work for me (it shows squares for all glyphs). Any idea?
include/vrv/toolkit.h
Outdated
* Render the page to the deviceContext. | ||
* Page number is 1-based. | ||
*/ | ||
bool RenderToCustomDevice(int pageNo, DeviceContext *deviceContext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename this to ::RenderToDeviceContext
// Copyright (c) Authors and others. All rights reserved. | ||
///////////////////////////////////////////////////////////////////////////// | ||
|
||
#ifndef __TEXTQUICKITEM_H__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be __VRV_QT_TEXTQUICKITEM_H__
// Copyright (c) Authors and others. All rights reserved. | ||
///////////////////////////////////////////////////////////////////////////// | ||
|
||
#ifndef __QTSCENEGRAPHDEVICECONTEXT_H__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be __VRV_QT_SCENEGRAPH_DC_H__
|
||
#include "devicecontext.h" | ||
|
||
namespace vrv_qt { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change to vrvQt
and also match the directory to ./include/vrvqt (and not verovio-qt)
// Copyright (c) Authors and others. All rights reserved. | ||
///////////////////////////////////////////////////////////////////////////// | ||
|
||
#ifndef __VEROVIOQTTOOLKIT_H__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be __VRV_QT_TOOLKIT_H__
. Also, since there is the namespace it should now be just toolkit.h/cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already commented on a previous change request from you that I'd also prefer toolkit.h/cpp, but thats not possible:
The file has been renamed to verovioqttoolkit.h/cpp. I would have preferred to just name it toolkit.h/cpp but that's not possible because the Verovio library requires include/vrv to be in the INCLUDEPATH and thus pollutes the . include path.
Changing that would require a bigger refactoring of the Verovio library:
- Do not specify include/vrv, include/midi, ... as include directories but only include/.
- Change all .h/.cpp files to include the subdirectory of the main include. E.g.
#include "vrv/page.h"
instead of#include "page.h"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Since we are in the extension of the Verovio library I would suggest qttoolkit.h/cpp. OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact you could refactor it the other way, that is, have only INCLUDEPATH += include/
in the Qt project (and not include/vrvqt
) and then do #include "vrvqt/toolkit.h"
. I am fine either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can have both path included, and then use give the subdirectory only for files that have a on conflict.
INCLUDEPATH += include/
INCLUDEPATH += include/vrvqt
{
INCLUDEPATH += ../../include/
INCLUDEPATH += ../../include/vrv
INCLUDEPATH += ../../include/pugi
INCLUDEPATH += ../../include/utf8
INCLUDEPATH += ../../libmei
LIBS += -L../../build -lverovio
}
And then do either:
#include "vrv/toolkit.h"
#include "vrvqt/toolkit.h"
For other files:
#include "textquickitem.h"
// Copyright (c) Authors and others. All rights reserved. | ||
///////////////////////////////////////////////////////////////////////////// | ||
|
||
#ifndef __VEROVIOQTVIEW_H__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here (just vrvQt::View) and __VRV_QT_VIEW_H__
/** | ||
* This class is a wrapper around the Verovio Toolkit (vrv::Toolkit). | ||
*/ | ||
class Toolkit : public QObject { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more comment: I think you could do even better with a multiple inheritance with something like:
class Toolkit : public QObject, public vrv::Toolkit
and avoid member duplication. You will probably have to make some member of vrv::Toolkit protected (and not private)
- Renaming of functions, classes, namespaces, directories, include-guards.
I've considered all but the last review comments. I prefer to keep vrvQt::Toolkit and vrv::Toolkit linked by composition instead of inheritance for following reasons:
Regarding the squares when using Leipzig or Gootville font: The fonts are loaded from the fontDirPath, specified in main.qml:53. Maybe it works if you specify an absolute path. The filenames are hard-coded in toolkit.cpp and should be Bravura-1.204.otf, Leipzig-5.2.ttf and Gootville-1.2.otf. In this branch these files exist. |
Thanks for the changes. It seems that the problem with the font is not related to the path but to the fact that it has to be installed on the computer. Leipzig works if I install it on my computer (os x 10.12). Could you double check it |
On my system I don't have any of the four used fonts installed. That's why I use QFontDatabase::addApplicationFont to add the fonts to the running application. Did you try to use an absolute path in main.qml for fontDirPath and it still didn't help? With my latest commit I added some warning outputs when adding a font. It will either output that the file cannot be found or a generic "Could not add font", which means the file exists, but there was some other problem. |
I've now removed the fontDirPath property, instead the font paths to the music font and verovio text font have to be set directly. I included the fonts in the resources of the verovio-qt-demo. This should improve compatibility on different platforms. |
Hello everyone,
this pull request adds support for the Qt toolkit.
In the last months I've examined some music engraving libraries and found Verovio to be the best suitable. Its layouting engine with the collision detection works really well and the code is clean and well structured.
I started by using Verovio as is and did all the rendering to SVG. Unfortunately SVG support in Qt is not the best, e.g. only supports SVG Tiny (see #332) and does not allow to update already painted elements (except by repainting). Therefore I quickly came up with the idea to provide a custom DeviceContext for Qt to directly draw to Qt's scene-graph and profit from direct OpenGL painting.
As I did not want to bloat the clean C++ library with conditionals I created the verovio-qt library as a wrapper around the original library. The main part is the QtSceneGraphDeviceContext which inherits the abstract DeviceContext. A user of the verovio-qt library uses the VerovioDoc and VerovioPage classes. They can also directly be used in QML. To showcase the usage of the verovio-qt library I also included a small demo application.
The Qt toolkit is mainly feature complete. I left out some rarely used draw instructions such as DrawEllipticArc.
Best regards
Jonathan