Google Summer of Code 2021 Work Product Submission
Introduction
Hello, my name is Panos Korovesis and during 2021 I was accepted in the Google Summer of Code program. I chose a project from LibreOffice and I worked under the mentorship of Tomaž Vajngerl and Miklos Vajna. The objective of the project was to complete the missing import/export tests of the SVM format and then separate the writing/reading functionality of the VCL Metafile to its own classes, in order to allow further refactoring of the VCL.
Technical Overview
This project can be broken down in five distinct phases.
- Phase One - Missing SVM Tests: This part included the completion of the commented out methods in svmtest.cxx. In some cases additions were required in mtfxmldump.cxx in order for the svm file to be produced.
- Phase Two - SvmReader: This part included the creation of a new class SvmReader.hxx in order to handle the reading functionality of the VCL. Reading is done with SvmReader::Read method, which works as follows:
- Sets up the stream, as was previously done in ReadGDIMetaFile
- For each MetaAction call the created MetaActionHandler
- The MetaActionHandler calls the appropriate read handler - which performs the reading - (e.g PixelHandler) for each MetaAction depending on the MetaActionType. The handlers are modified versions of the MetaAction::Read methods. Note: In order for the read handlers to work, Set methods had to be created for each MetaAct’s protected members (one can be seen here).
- Phase Three - SvmWriter: This part included the creation of a new class SvmWriter.hxx in order to handle the writing functionality of the VCL. Writing is done with SvmWriter::Write method, which works as follows:
- Sets up the stream, as was previously done in GDIMetaFile::Write
- For each MetaAction in the MetaFile, call the created MetaActionHandler
- The MetaActionHandler calls the appropriate write handler - which performs the writing - (e.g PointHandler) for each MetaAction depending on the MetaActionType. The handlers are modified versions of the MetaAction::Write methods.
- Phase Four - Replacing: The reading/writing was performed by four methods. Those are: GDIMetaFile::Read, GDIMetaFile::Write, ReadGDIMetaFile, WriteGDIMetaFile. Whereas the new functionality is performed by SvmWriter::Write and SvmReader::Read. This part included the replacement of the method calls of the methods mentioned above with the new ones (SvmWriter::Write, SvmReader::Read) Note: GDIMetaFile::GetChecksum had to be moved in SvmWriter because it was using the MetaAction::Write method.
- Phase Five - Cleanup: This part included the deletion of methods that were no longer in use. Those were:
- GDIMetaFile::Write
- GDIMetaFile::Read
- WriteGDIMetaFile
- ReadGDIMetaFile
- MetaAction::Write
- MetaAction::Read
- GDIMetaFile::GetChecksum
Commits
A list with all the commits can be found at the bottom of this post
Some important commits for each phase are listed below:
Phase One The commits regarding this phase start from Add RefPoint cppunit test to vcl and end at Add FloatTransparent cppunit test to vcl.
Example: Add Comment cppunit test to vcl
- Fill the TestComment method with the required elements to be tested. They are then written in a .svm file in xml format
- Create a CheckComment method, which checks if the Comment attributes declared in the method above are the expected in the xml
- Modify mtfxmldump.cxx to format the xml output in the format we need
Phase Two The commits regarding this phase start from Create Separate SvmReader class and end at Add Handler for MetaAction Read.
Example: Create Separate SvmReader class
- Create the required files for a new class and update the appropriate makefile
- Create a constructor
- Create the Read method. It sets up the stream and calls the MetaActionHandler. At this stage the MetaActionHandler uses the original read functionality (MetaAction::Read). The next commits start replacing it with the new one.
- Update svmtest.cxx in order to use SvmReader::Read instead of GDIMetaFile::Read
Example: Add Handler for MetaPoint Read
- Create the PointHandler
- Create Set methods for MetaPointAction private members, as they are required by the PointHandler
- Adjust the MetaActionHandler to call the PointHandler where needed. Thus, the new read functionality is used instead of the MetaPointAction::Read
Phase Three The commits regarding this phase start from Create SvmWriter class and end at Add Handler for TextLineColor Write
Example: Create SvmWriter class
- Create the required files for a new class and update the appropriate makefile
- Create a constructor
- Create the MetaActionHandler and the ActionHandler which replaces MetaAction::Write.
- Create the Write method. It sets up the stream and calls the MetaActionHandler. At this stage the MetaActionHandler uses the original read functionality (MetaAction::Write) for all actions except MetaAction. The next commits continue replacing with the new one.
- Update svmtest.cxx in order to use SvmWriter::Write instead of GDIMetaFile::Write
Example: Add Handler for Ellipse Write
- Create the EllipseHandler
- Adjust the MetaActionHandler to call the EllipseHandler where needed. Thus, the new read functionality is used instead of the MetaPointAction::Write
Phase Four The commits regarding this phase start with “Replace”
Example: Replace ReadGDIMetaFile with Svmreader::Read
-
Removes the old method call
-
Creates a SvmReader object and calls SvmReader::Read, thus replacing the old Read with the new
Note: These steps are repeated for each file that needs replacing
Phase Five The commits regarding this phase start with “Remove”. It also includes the commit Move GDIMetaFile::GetChecksum to SvmWriter::GetChecksum
Example: Remove unused methods from gdimtf.hxx
-
Removes GDIMetaFile::Read
-
Removes GDIMetaFile::Write
-
Removes ReadGDIMetaFile
-
Removes WriteGDIMetaFile
Note: This can be done, as the functionality of the removed methods is covered by SvmReader, SvmWriter.
Example: Move GDIMetaFile::GetChecksum to SvmWriter::GetChecksum
-
Moves the method to SvmWriter while applying any changes needed in order to be compatible
-
Removes the method from it’s initial location
Note: This change was required as the method was using MetaAction::Write, which is replaced by the SvmWriter.
Next Steps
The remaining steps for the completion of the project are
- Go through the tests of the svm format trying to find edge cases and if so, write tests for them
Those steps do not need to be implemented by someone else however as I am determined to see this project to the end, even if it it goes beyond the GSoC Coding period.
Conclusion
Working at LibreOffice was a beautiful experience. Getting in touch with people all over the world while aiming at the same goal was something new for me, but definitely something I will seek in the future! I would also like to thank the dev community for it’s constant support on all my questions (silly or not) and especially my mentors Tomaž Vajngerl, Miklos Vajna for their continuous support as without them I would not be able to progress. Lastly, as I had a great experience, I plan to continue contributing to LibreOffice in the feature! Sere you all around!
Commit List
All the commits regarding the project and thus listed below, have been successfully merged.
The commits are:
- https://gerrit.libreoffice.org/c/core/+/116780
- https://gerrit.libreoffice.org/c/core/+/116819
- https://gerrit.libreoffice.org/c/core/+/116967
- https://gerrit.libreoffice.org/c/core/+/116959
- https://gerrit.libreoffice.org/c/core/+/117153
- https://gerrit.libreoffice.org/c/core/+/117232
- https://gerrit.libreoffice.org/c/core/+/117245
- https://gerrit.libreoffice.org/c/core/+/117155
- https://gerrit.libreoffice.org/c/core/+/117368
- https://gerrit.libreoffice.org/c/core/+/117575
- https://gerrit.libreoffice.org/c/core/+/117702
- https://gerrit.libreoffice.org/c/core/+/117694
- https://gerrit.libreoffice.org/c/core/+/118143
- https://gerrit.libreoffice.org/c/core/+/118275
- https://gerrit.libreoffice.org/c/core/+/118217
- https://gerrit.libreoffice.org/c/core/+/118396
- https://gerrit.libreoffice.org/c/core/+/118398
- https://gerrit.libreoffice.org/c/core/+/118399
- https://gerrit.libreoffice.org/c/core/+/118403
- https://gerrit.libreoffice.org/c/core/+/118433
- https://gerrit.libreoffice.org/c/core/+/118473
- https://gerrit.libreoffice.org/c/core/+/118545
- https://gerrit.libreoffice.org/c/core/+/118550
- https://gerrit.libreoffice.org/c/core/+/118565
- https://gerrit.libreoffice.org/c/core/+/118566
- https://gerrit.libreoffice.org/c/core/+/118598
- https://gerrit.libreoffice.org/c/core/+/118608
- https://gerrit.libreoffice.org/c/core/+/118610
- https://gerrit.libreoffice.org/c/core/+/118633
- https://gerrit.libreoffice.org/c/core/+/118636
- https://gerrit.libreoffice.org/c/core/+/118637
- https://gerrit.libreoffice.org/c/core/+/118653
- https://gerrit.libreoffice.org/c/core/+/118665
- https://gerrit.libreoffice.org/c/core/+/118667
- https://gerrit.libreoffice.org/c/core/+/118672
- https://gerrit.libreoffice.org/c/core/+/118673
- https://gerrit.libreoffice.org/c/core/+/118674
- https://gerrit.libreoffice.org/c/core/+/118677
- https://gerrit.libreoffice.org/c/core/+/118698
- https://gerrit.libreoffice.org/c/core/+/118829
- https://gerrit.libreoffice.org/c/core/+/118833
- https://gerrit.libreoffice.org/c/core/+/118834
- https://gerrit.libreoffice.org/c/core/+/118836
- https://gerrit.libreoffice.org/c/core/+/118830
- https://gerrit.libreoffice.org/c/core/+/118837
- https://gerrit.libreoffice.org/c/core/+/118845
- https://gerrit.libreoffice.org/c/core/+/118892
- https://gerrit.libreoffice.org/c/core/+/118894
- https://gerrit.libreoffice.org/c/core/+/118895
- https://gerrit.libreoffice.org/c/core/+/118896
- https://gerrit.libreoffice.org/c/core/+/118955
- https://gerrit.libreoffice.org/c/core/+/118956
- https://gerrit.libreoffice.org/c/core/+/118957
- https://gerrit.libreoffice.org/c/core/+/118967
- https://gerrit.libreoffice.org/c/core/+/118968
- https://gerrit.libreoffice.org/c/core/+/118979
- https://gerrit.libreoffice.org/c/core/+/118980
- https://gerrit.libreoffice.org/c/core/+/118981
- https://gerrit.libreoffice.org/c/core/+/119092
- https://gerrit.libreoffice.org/c/core/+/119170
- https://gerrit.libreoffice.org/c/core/+/119171
- https://gerrit.libreoffice.org/c/core/+/119192
- https://gerrit.libreoffice.org/c/core/+/119193
- https://gerrit.libreoffice.org/c/core/+/119194
- https://gerrit.libreoffice.org/c/core/+/119537
- https://gerrit.libreoffice.org/c/core/+/119538
- https://gerrit.libreoffice.org/c/core/+/119539
- https://gerrit.libreoffice.org/c/core/+/119541
- https://gerrit.libreoffice.org/c/core/+/119580
- https://gerrit.libreoffice.org/c/core/+/119591
- https://gerrit.libreoffice.org/c/core/+/119592
- https://gerrit.libreoffice.org/c/core/+/119593
- https://gerrit.libreoffice.org/c/core/+/119594
- https://gerrit.libreoffice.org/c/core/+/119733
- https://gerrit.libreoffice.org/c/core/+/119734
- https://gerrit.libreoffice.org/c/core/+/119735
- https://gerrit.libreoffice.org/c/core/+/119736
- https://gerrit.libreoffice.org/c/core/+/119737
- https://gerrit.libreoffice.org/c/core/+/119738
- https://gerrit.libreoffice.org/c/core/+/119846
- https://gerrit.libreoffice.org/c/core/+/119898
- https://gerrit.libreoffice.org/c/core/+/119899
- https://gerrit.libreoffice.org/c/core/+/119900
- https://gerrit.libreoffice.org/c/core/+/119901
- https://gerrit.libreoffice.org/c/core/+/119902
- https://gerrit.libreoffice.org/c/core/+/119903
- https://gerrit.libreoffice.org/c/core/+/119920
- https://gerrit.libreoffice.org/c/core/+/119921
- https://gerrit.libreoffice.org/c/core/+/119922
- https://gerrit.libreoffice.org/c/core/+/119923
- https://gerrit.libreoffice.org/c/core/+/119924
- https://gerrit.libreoffice.org/c/core/+/119925
- https://gerrit.libreoffice.org/c/core/+/119963
- https://gerrit.libreoffice.org/c/core/+/119964
- https://gerrit.libreoffice.org/c/core/+/119965
- https://gerrit.libreoffice.org/c/core/+/119966
- https://gerrit.libreoffice.org/c/core/+/119967
- https://gerrit.libreoffice.org/c/core/+/119968
- https://gerrit.libreoffice.org/c/core/+/120106
- https://gerrit.libreoffice.org/c/core/+/120107
- https://gerrit.libreoffice.org/c/core/+/120108
- https://gerrit.libreoffice.org/c/core/+/120109
- https://gerrit.libreoffice.org/c/core/+/120110
- https://gerrit.libreoffice.org/c/core/+/120111
- https://gerrit.libreoffice.org/c/core/+/120153
- https://gerrit.libreoffice.org/c/core/+/120154
- https://gerrit.libreoffice.org/c/core/+/120155
- https://gerrit.libreoffice.org/c/core/+/120156
- https://gerrit.libreoffice.org/c/core/+/120157
- https://gerrit.libreoffice.org/c/core/+/120158
- https://gerrit.libreoffice.org/c/core/+/120256
- https://gerrit.libreoffice.org/c/core/+/120257
- https://gerrit.libreoffice.org/c/core/+/120258
- https://gerrit.libreoffice.org/c/core/+/120259
- https://gerrit.libreoffice.org/c/core/+/120263
- https://gerrit.libreoffice.org/c/core/+/120264
- https://gerrit.libreoffice.org/c/core/+/120306
- https://gerrit.libreoffice.org/c/core/+/120307
- https://gerrit.libreoffice.org/c/core/+/120308
- https://gerrit.libreoffice.org/c/core/+/120309
- https://gerrit.libreoffice.org/c/core/+/120312
- https://gerrit.libreoffice.org/c/core/+/120313
- https://gerrit.libreoffice.org/c/core/+/120349
- https://gerrit.libreoffice.org/c/core/+/120350
- https://gerrit.libreoffice.org/c/core/+/120351
- https://gerrit.libreoffice.org/c/core/+/120372
- https://gerrit.libreoffice.org/c/core/+/120376
- https://gerrit.libreoffice.org/c/core/+/120408
- https://gerrit.libreoffice.org/c/core/+/120409
- https://gerrit.libreoffice.org/c/core/+/120414
- https://gerrit.libreoffice.org/c/core/+/120471