1
//--------------------------------------------------------------------------------------
2
// This file is part of the Lomse library.
3
// Copyright (c) 2010 Lomse project
5
// Lomse is free software; you can redistribute it and/or modify it under the
6
// terms of the GNU General Public License as published by the Free Software Foundation,
7
// either version 3 of the License, or (at your option) any later version.
9
// Lomse is distributed in the hope that it will be useful, but WITHOUT ANY
10
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11
// PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
// You should have received a copy of the GNU General Public License along
14
// with Lomse; if not, see <http://www.gnu.org/licenses/>.
16
// For any comment, suggestion or feature request, please contact the manager of
17
// the project at cecilios@users.sourceforge.net
19
//-------------------------------------------------------------------------------------
21
#include "lomse_ldp_exporter.h"
25
#include "lomse_internal_model.h"
26
#include "lomse_im_note.h"
32
#define lml_LDP_INDENT_STEP 3
34
//-------------------------------------------------------------------------------------
36
//-------------------------------------------------------------------------------------
40
LdpExporter* m_pExporter;
41
stringstream m_source;
44
LdpGenerator(LdpExporter* pExporter) : m_pExporter(pExporter) {}
46
virtual std::string generate_source() = 0;
51
void add_indent_spaces();
52
void add_element_name(const std::string& name, ImoObj* pImo);
53
void add_source_for(ImoObj* pImo);
54
void source_for_base_staffobj(ImoObj* pImo);
55
void source_for_base_componentobj(ImoObj* pImo);
56
void source_for_base_docobj(ImoObj* pImo);
57
void source_for_base_imobj(ImoObj* pImo);
58
void source_for_auxobj(ImoObj* pImo);
59
void increment_indent();
60
void decrement_indent();
66
//-------------------------------------------------------------------------------------
67
// generators for specific elements
68
//-------------------------------------------------------------------------------------
72
//-------------------------------------------------------------------------------------
73
class ErrorLdpGenerator : public LdpGenerator
76
ErrorLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter) {}
78
std::string generate_source()
81
m_source << "(TODO: Add this element to LdpExporter::new_generator)";
82
return m_source.str();
88
//-------------------------------------------------------------------------------------
89
class ClefLdpGenerator : public LdpGenerator
95
ClefLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
97
m_pObj = dynamic_cast<ImoClef*>(pImo);
100
std::string generate_source()
103
add_element_name("clef", m_pObj);
105
source_for_base_staffobj(m_pObj);
107
return m_source.str();
114
m_source << LdpExporter::clef_type_to_ldp( m_pObj->get_clef_type() );
120
// lenmusdoc generator
121
//-------------------------------------------------------------------------------------
122
class LenmusdocLdpGenerator : public LdpGenerator
128
LenmusdocLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
130
m_pObj = dynamic_cast<ImoDocument*>(pImo);
133
std::string generate_source()
136
add_element_name("lenmusdoc", m_pObj);
140
return m_source.str();
147
m_source << "(vers ";
148
m_source << m_pObj->get_version();
154
m_source << "(content";
155
int numItems = m_pObj->get_num_content_items();
156
for (int i=0; i < numItems; i++)
159
add_source_for( m_pObj->get_content_item(i) );
168
//-------------------------------------------------------------------------------------
169
class NoteLdpGenerator : public LdpGenerator
175
NoteLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
177
m_pObj = dynamic_cast<ImoNote*>(pImo);
180
std::string generate_source()
183
add_element_name("n", m_pObj);
186
source_for_base_staffobj(m_pObj);
188
return m_source.str();
195
m_source << " (TODO: pitch)";
200
m_source << " (TODO: duration)";
206
// staffobj generator
207
//-------------------------------------------------------------------------------------
208
class StaffObjLdpGenerator : public LdpGenerator
214
StaffObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
216
m_pObj = dynamic_cast<ImoStaffObj*>(pImo);
219
std::string generate_source()
222
source_for_base_componentobj(m_pObj);
223
return m_source.str();
230
if (!m_pObj->is_key_signature() //KS, TS & barlines are common to all staves.
231
&& !m_pObj->is_time_signature()
232
&& !m_pObj->is_barline() )
234
m_source << " p" << (m_pObj->get_staff() + 1);
240
// componentobj generator
241
//-------------------------------------------------------------------------------------
242
class ComponentObjLdpGenerator : public LdpGenerator
245
ImoComponentObj* m_pObj;
248
ComponentObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
250
m_pObj = dynamic_cast<ImoComponentObj*>(pImo);
253
std::string generate_source()
257
source_for_base_docobj(m_pObj);
258
return m_source.str();
265
if (!m_pObj->is_visible())
266
m_source << " (visible no)";
271
//color (if not black)
272
rgba16 color = m_pObj->get_color();
273
if (color != rgba16(0,0,0))
274
m_source << " (color " << LdpExporter::color_to_ldp(color) << ")";
280
//-------------------------------------------------------------------------------------
281
class DocObjLdpGenerator : public LdpGenerator
287
DocObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
289
m_pObj = dynamic_cast<ImoDocObj*>(pImo);
292
std::string generate_source()
296
source_for_base_imobj(m_pObj);
297
return m_source.str();
302
void add_user_location()
304
Tenths ux = m_pObj->get_user_location_x();
306
m_source << " (dx " << LdpExporter::float_to_string(ux) << ")";
308
Tenths uy = m_pObj->get_user_location_y();
310
m_source << " (dy " << LdpExporter::float_to_string(uy) << ")";
313
void add_attachments()
315
if (m_pObj->get_num_attachments() > 0)
318
// std::list<ImoAuxObj*>& attachments = m_pObj->get_attachments();
319
// std::list<ImoAuxObj*>::iterator it;
320
// for (it = attachments.begin(); it != attachments.end(); ++it)
322
// ImoAuxObj* pAuxObj = *it;
323
// if ( pAuxObj->is_relobj() )
325
// ImRelObj* pRO = dynamic_cast<ImRelObj*)>(pAuxObj);
327
// //exclude beams, as source code for them is generted in lmNote.
328
// //AWARE. This is necessary because LDP parser needs to have beam
329
// //info to crete the note, before it can process any other attachment.
330
// //Therefore, it was decided to generate beam tag before generating
331
// //attachment tags.
332
// if (!pRO->IsBeam())
334
// if ( pRO->GetStartNoteRest() == (lmNoteRest*)this )
335
// m_source += pRO->SourceLDP_First(nIndent, fUndoData, (lmNoteRest*)this);
336
// else if ( pRO->GetEndNoteRest() == (lmNoteRest*)this )
337
// m_source += pRO->SourceLDP_Last(nIndent, fUndoData, (lmNoteRest*)this);
339
// m_source += pRO->SourceLDP_Middle(nIndent, fUndoData, (lmNoteRest*)this);
342
// else if ( pAuxObj->IsRelObX() )
344
// lmRelObX* pRO = (lmRelObX*)pAuxObj;
346
// //exclude beams, as source code for them is generted in lmNote.
347
// //AWARE. This is necessary because LDP parser needs to have beam
348
// //info to crete the note, before it can process any other attachment.
349
// //Therefore, it was decided to generate beam tag before generating
350
// //attachment tags.
351
// if (!pRO->IsBeam())
353
// if (pRO->GetStartSO() == this)
354
// m_source += pRO->SourceLDP_First(nIndent, fUndoData, this);
355
// else if (pRO->GetEndSO() == this)
356
// m_source += pRO->SourceLDP_Last(nIndent, fUndoData, this);
358
// m_source += pRO->SourceLDP_Middle(nIndent, fUndoData, this);
362
// source_for_auxobj(pAuxObj);
371
//-------------------------------------------------------------------------------------
372
class ImObjLdpGenerator : public LdpGenerator
378
ImObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
383
std::string generate_source()
385
return m_source.str();
391
//-------------------------------------------------------------------------------------
392
// LdpGenerator implementation
393
//-------------------------------------------------------------------------------------
395
void LdpGenerator::start_element()
400
void LdpGenerator::end_element()
403
if (m_pExporter->get_indent() > 0)
407
void LdpGenerator::add_indent_spaces()
410
int indent = m_pExporter->get_indent() * lml_LDP_INDENT_STEP;
418
void LdpGenerator::add_element_name(const std::string& name, ImoObj* pImo)
420
m_source << "(" << name;
421
if (m_pExporter->get_add_id())
422
m_source << "#" << std::dec << pImo->get_id();
426
void LdpGenerator::add_source_for(ImoObj* pImo)
428
m_source << m_pExporter->get_source(pImo);
431
void LdpGenerator::source_for_base_staffobj(ImoObj* pImo)
433
LdpGenerator* pGen = new StaffObjLdpGenerator(pImo, m_pExporter);
434
m_source << pGen->generate_source();
437
void LdpGenerator::source_for_base_componentobj(ImoObj* pImo)
439
LdpGenerator* pGen = new ComponentObjLdpGenerator(pImo, m_pExporter);
440
m_source << pGen->generate_source();
443
void LdpGenerator::source_for_base_docobj(ImoObj* pImo)
445
LdpGenerator* pGen = new DocObjLdpGenerator(pImo, m_pExporter);
446
m_source << pGen->generate_source();
449
void LdpGenerator::source_for_base_imobj(ImoObj* pImo)
451
LdpGenerator* pGen = new ImObjLdpGenerator(pImo, m_pExporter);
452
m_source << pGen->generate_source();
455
void LdpGenerator::source_for_auxobj(ImoObj* pImo)
457
m_source << m_pExporter->get_source(pImo);
460
void LdpGenerator::increment_indent()
465
void LdpGenerator::decrement_indent()
472
//-------------------------------------------------------------------------------------
473
// LdpExporter implementation
474
//-------------------------------------------------------------------------------------
476
LdpExporter::LdpExporter()
482
LdpExporter::~LdpExporter()
486
std::string LdpExporter::get_source(ImoObj* pImo)
488
LdpGenerator* pGen = new_generator(pImo);
489
std::string source = pGen->generate_source();
494
LdpGenerator* LdpExporter::new_generator(ImoObj* pImo)
498
switch(pImo->get_obj_type())
500
// case ImoObj::k_beam_info: return new XxxxxxxLdpGenerator(pImo, this);
501
// case ImoObj::k_bezier_info: return new XxxxxxxLdpGenerator(pImo, this);
502
// case ImoObj::k_color_info: return new XxxxxxxLdpGenerator(pImo, this);
503
// case ImoObj::k_instr_group: return new XxxxxxxLdpGenerator(pImo, this);
504
// case ImoObj::k_midi_info: return new XxxxxxxLdpGenerator(pImo, this);
505
// case ImoObj::k_option: return new XxxxxxxLdpGenerator(pImo, this);
506
// case ImoObj::k_system_info: return new XxxxxxxLdpGenerator(pImo, this);
507
// case ImoObj::k_tie_info: return new XxxxxxxLdpGenerator(pImo, this);
508
// case ImoObj::k_tuplet_info: return new XxxxxxxLdpGenerator(pImo, this);
509
case ImoObj::k_document: return new LenmusdocLdpGenerator(pImo, this);
510
// case ImoObj::k_content: return new XxxxxxxLdpGenerator(pImo, this);
511
// case ImoObj::k_music_data: return new XxxxxxxLdpGenerator(pImo, this);
512
// case ImoObj::k_instrument: return new XxxxxxxLdpGenerator(pImo, this);
513
// case ImoObj::k_score: return new XxxxxxxLdpGenerator(pImo, this);
514
// case ImoObj::k_barline: return new XxxxxxxLdpGenerator(pImo, this);
515
case ImoObj::k_clef: return new ClefLdpGenerator(pImo, this);
516
// case ImoObj::k_key_signature: return new XxxxxxxLdpGenerator(pImo, this);
517
// case ImoObj::k_time_signature: return new XxxxxxxLdpGenerator(pImo, this);
518
case ImoObj::k_note: return new NoteLdpGenerator(pImo, this);
519
// case ImoObj::k_rest: return new XxxxxxxLdpGenerator(pImo, this);
520
// case ImoObj::k_go_back_fwd: return new XxxxxxxLdpGenerator(pImo, this);
521
// case ImoObj::k_metronome_mark: return new XxxxxxxLdpGenerator(pImo, this);
522
// case ImoObj::k_control: return new XxxxxxxLdpGenerator(pImo, this);
523
// case ImoObj::k_spacer: return new XxxxxxxLdpGenerator(pImo, this);
524
// case ImoObj::k_figured_bass: return new XxxxxxxLdpGenerator(pImo, this);
525
// case ImoObj::k_score_text: return new XxxxxxxLdpGenerator(pImo, this);
526
// case ImoObj::k_fermata: return new XxxxxxxLdpGenerator(pImo, this);
527
// case ImoObj::k_tie: return new XxxxxxxLdpGenerator(pImo, this);
528
// case ImoObj::k_beam: return new XxxxxxxLdpGenerator(pImo, this);
529
// case ImoObj::k_tuplet: return new XxxxxxxLdpGenerator(pImo, this);
531
return new ErrorLdpGenerator(pImo, this);
539
std::string LdpExporter::clef_type_to_ldp(int clefType)
541
//AWARE: indexes in correspondence with enum ImoClef::k__type
542
static const std::string name[] = {
563
static const std::string undefined = "undefined";
566
if (clefType == ImoClef::k_undefined)
569
return name[clefType];
572
std::string LdpExporter::color_to_ldp(rgba16& color)
576
source << std::hex << setfill('0') << setw(2) << color.r;
577
source << std::hex << setfill('0') << setw(2) << color.g;
578
source << std::hex << setfill('0') << setw(2) << color.b;
579
source << std::hex << setfill('0') << setw(2) << color.a;
583
std::string LdpExporter::float_to_string(float num)
585
return "(TODO: float_to_string)";