Funcionalidades Ayuda Descargar

Lomse Hacking Guide

1.1. Lomse at glance

Lomse main functionality is to render any LenMus document (i.e. a music score) you choose or you build. The way the document content is represented is described in the LDP language specification.

The Lomse’s main components are:

  • The Document - Lomse library main class is Document. It represents a LenMus document. You can see LenMus documents as something similar to HTML documents but with the ability of also including music scores. All other important classes are built around the Document, either for displaying it or for building/modifying its content.
  • The rendering engine - It is responsible for transforming the information contained in the Document into a bitmap (or other format) for displaying it on the screen.
  • The MVC model - For marshaling the actions between the user application, the Document and the rendering engine, Lomse uses a Model-View-Controller (MVC) architecture. Multiple simultaneous views of the document are supported.
  • The sound engine - It is responsible for transforming the information contained in the Document into a stream of events for generating sound and graphical feedback (notes highlight, moving tempo line)
  • The LomseDoorway - It is the access point to the Lomse library. It must be used by the user application at two points:
    1. Before using the Lomse library it is necessary to initialize it. This means setting up certain options about rendering and event handling.
    2. Later, the user application has to use LomseDoorway for requesting to create Document objects and for accessing them.

1.1.1. Building the document

The main content of a Document is the InternalModel. It is something similar to the DOM in HTML. By accessing and modifying this internal model you have full control over the document content.

A Document can be created:

  • From a file containing the document source code (LDP language)
  • From a string, also containing LDP source code.
  • Or, dynamically, by program.

The LDP compiler follows a typical structure. A tokenizer class LdpTokenizer is responsible for the lexical analysis, grouping the input into language tokens. The LdpParser class does the syntactical analysis, and produces a parse tree. Then the Analyser class is responsible for syntax validation and semantic analysis; it adds information to the parse tree. Finally, the ModelBuilder class performs the code generation phase.

The Document can also be created and modified by program. Commands on the Document and direct manipulation of the InternalModel give full flexibility for this. An special LDP tag dynamic instructs the Analyser to require from user application the content to be inserted at that point. This is something analogous to the HTML <object> tag.

All these issues are described in Part I: Building the document.

1.1.2. Rendering the document

The InternalModel is a collection of ‘internal model objects’ (Imo objects) that form a purpose independent representation of the document content. From it, any other specific representation can be derived.

For displaying a document, two steps are performed:

  1. The InternalModel is traversed and a GraphicModel is built. It is a collection of GmoBox and GmoShape objects.
  2. The GraphicModel is traversed and its objects rendered to create a bitmap or other desired representation.

Involved objects:

  • Boxes and Shapes (GmoBox and GmoShape objects) - They are the ‘bricks’ that form the GraphicModel.
  • Layouter objects - Its main responsibility is to organise the space, creating areas for placing content. In practice, this implies that layouters main objective is to create the GmoBox objects.
  • Engraver objects - Its main responsibility is to create the symbols (lines, texts, music symbols, etc.) within the specified areas. In practice, this implies that their main objective is to create the GmoShape objects.
  • Drawer - The objects that form the GraphicModel, that is GmoBox and GmoShape objects, are responsible for rendering themselves by issuing drawing commands. The Drawer object is responsible for transforming these commands into something understandable by the underlying rendering engine. Currently only ScreenDrawer class is implemented and it behaves as a vertex source for ScreenRenderer class. But other derived classes would be possible, for instance to generate SVG commands.
  • Calligrapher - It is a helper class specialized in managing fonts and drawing texts.
  • Renderer - It is the front-end object for the desired rendering pipeline. For instance, class ScreenRenderer transforms vertices and paths received from ScreenDrawer into a bitmap.

The result of this process is the creation of a bitmap (or other desired output) for displaying the document content.

All these issues are described in Part II: Rendering the document.

1.1.3. Presentation and user interaction

The Lomse MVC architecture is composed by several objects. The main ones are:

  • The View - It is an observer of the Document`, and its main responsibility is to render it. The rendering type depends on the specific view class used. For instance, class GraphicView renders the document on a bitmap. Other classes would be possible (i.e. a view class to render the document as an SVG stream) but for now I have only implemented several variations of GraphicView (VerticalBookView, HorizontalBookView, and SimpleView). The model supports having many simultaneous views for a document.
  • The Interactor - It is a facade object and its main responsibility is to transform user application actions into commands on the document and the MVC model. Therefore, you can consider it as the controller in the MVC model. The Interactor is the owner of the View, and there is an Interactor per View.
  • The Presenter - It is the owner of the Document and of all its Interactor objects. The Presenter‘s main responsibility is to build (and delete) the MVC model for a Document.

All these issues are described in Part III: Presentation and user interaction.

1.1.4. Playing back scores

As said, the InternalModel is a collection of ‘internal model objects’ (Imo objects), that form an purpose independent representation of the document content. From it, any other specific purpose representation can be derived.

For playing back scores, two steps are performed:

  • The InternalModel is parsed to build the sound model
  • The sound model is traversed and two kind of events are generated:
    1. Sound events, for generating sounds
    2. Highlight events, for adding visual effects to the displayed score (notes highlight, moving tempo line, ...).

Involved objects:

  • SoundPlayer
  • SoundEventsTable

All these issues are described in Part IV: Playing back scores.

1.1.5. Other issues

For orchestrating all these pieces some issues have to be taken into account. Therefore, some additional important objects were created. For instance, I already introduced the LomseDoorway, whose main responsibility is allowing user application to initialize the library and for requesting to create Document objects.

All these additional issues are described in Part V: Other issues.