~s-cecilio/lomse/master

« back to all changes in this revision

Viewing changes to src/exporters/lomse_ldp_exporter.cpp

  • Committer: cecilios
  • Date: 2010-10-10 13:35:19 UTC
  • Revision ID: git-v1:2b333198c3033525d15763b84eaf79dac9fdab80
Preparing to use CMake. Updating with new code and missing files. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//--------------------------------------------------------------------------------------
 
2
//  This file is part of the Lomse library.
 
3
//  Copyright (c) 2010 Lomse project
 
4
//
 
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.
 
8
//
 
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.
 
12
//
 
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/>.
 
15
//  
 
16
//  For any comment, suggestion or feature request, please contact the manager of
 
17
//  the project at cecilios@users.sourceforge.net
 
18
//
 
19
//-------------------------------------------------------------------------------------
 
20
 
 
21
#include "lomse_ldp_exporter.h"
 
22
 
 
23
#include <iostream>
 
24
#include <iomanip>
 
25
#include "lomse_internal_model.h"
 
26
#include "lomse_im_note.h"
 
27
 
 
28
 
 
29
namespace lomse
 
30
{
 
31
 
 
32
#define lml_LDP_INDENT_STEP  3
 
33
 
 
34
//-------------------------------------------------------------------------------------
 
35
// LdpGenerator
 
36
//-------------------------------------------------------------------------------------
 
37
class LdpGenerator
 
38
{
 
39
protected:
 
40
    LdpExporter* m_pExporter;
 
41
    stringstream m_source;
 
42
 
 
43
public:
 
44
    LdpGenerator(LdpExporter* pExporter) : m_pExporter(pExporter) {}
 
45
 
 
46
    virtual std::string generate_source() = 0;
 
47
 
 
48
protected:
 
49
    void start_element();
 
50
    void end_element();
 
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();
 
61
 
 
62
};
 
63
 
 
64
 
 
65
 
 
66
//-------------------------------------------------------------------------------------
 
67
// generators for specific elements
 
68
//-------------------------------------------------------------------------------------
 
69
 
 
70
 
 
71
// Error generator
 
72
//-------------------------------------------------------------------------------------
 
73
class ErrorLdpGenerator : public LdpGenerator
 
74
{
 
75
public:
 
76
    ErrorLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter) {}
 
77
 
 
78
    std::string generate_source()
 
79
    {
 
80
        m_source.clear();
 
81
        m_source << "(TODO: Add this element to LdpExporter::new_generator)";
 
82
        return m_source.str();
 
83
    }
 
84
};
 
85
 
 
86
 
 
87
// clef generator
 
88
//-------------------------------------------------------------------------------------
 
89
class ClefLdpGenerator : public LdpGenerator
 
90
{
 
91
protected:
 
92
    ImoClef* m_pObj;
 
93
 
 
94
public:
 
95
    ClefLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
96
    {
 
97
        m_pObj = dynamic_cast<ImoClef*>(pImo);
 
98
    }
 
99
 
 
100
    std::string generate_source()
 
101
    {
 
102
        start_element();
 
103
        add_element_name("clef", m_pObj);
 
104
        add_type();
 
105
        source_for_base_staffobj(m_pObj);
 
106
        end_element();
 
107
        return m_source.str();
 
108
    }
 
109
 
 
110
protected:
 
111
 
 
112
    void add_type()
 
113
    {
 
114
        m_source << LdpExporter::clef_type_to_ldp( m_pObj->get_clef_type() );
 
115
    }
 
116
 
 
117
};
 
118
 
 
119
 
 
120
// lenmusdoc generator
 
121
//-------------------------------------------------------------------------------------
 
122
class LenmusdocLdpGenerator : public LdpGenerator
 
123
{
 
124
protected:
 
125
    ImoDocument* m_pObj;
 
126
 
 
127
public:
 
128
    LenmusdocLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
129
    {
 
130
        m_pObj = dynamic_cast<ImoDocument*>(pImo);
 
131
    }
 
132
 
 
133
    std::string generate_source()
 
134
    {
 
135
        start_element();
 
136
        add_element_name("lenmusdoc", m_pObj);
 
137
        add_version();
 
138
        add_content();
 
139
        end_element();
 
140
        return m_source.str();
 
141
    }
 
142
 
 
143
protected:
 
144
 
 
145
    void add_version()
 
146
    {
 
147
        m_source << "(vers ";
 
148
        m_source << m_pObj->get_version();
 
149
        m_source << ") ";
 
150
    }
 
151
 
 
152
    void add_content()
 
153
    {
 
154
        m_source << "(content";
 
155
        int numItems = m_pObj->get_num_content_items();
 
156
        for (int i=0; i < numItems; i++)
 
157
        {
 
158
            m_source << " ";
 
159
            add_source_for( m_pObj->get_content_item(i) );
 
160
        }
 
161
        m_source << ")";
 
162
    }
 
163
 
 
164
};
 
165
 
 
166
 
 
167
// note generator
 
168
//-------------------------------------------------------------------------------------
 
169
class NoteLdpGenerator : public LdpGenerator
 
170
{
 
171
protected:
 
172
    ImoNote* m_pObj;
 
173
 
 
174
public:
 
175
    NoteLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
176
    {
 
177
        m_pObj = dynamic_cast<ImoNote*>(pImo);
 
178
    }
 
179
 
 
180
    std::string generate_source()
 
181
    {
 
182
        start_element();
 
183
        add_element_name("n", m_pObj);
 
184
        add_pitch();
 
185
        add_duration();
 
186
        source_for_base_staffobj(m_pObj);
 
187
        end_element();
 
188
        return m_source.str();
 
189
    }
 
190
 
 
191
protected:
 
192
 
 
193
    void add_pitch()
 
194
    {
 
195
        m_source << " (TODO: pitch)";
 
196
    }
 
197
 
 
198
    void add_duration()
 
199
    {
 
200
        m_source << " (TODO: duration)";
 
201
    }
 
202
 
 
203
};
 
204
 
 
205
 
 
206
// staffobj generator
 
207
//-------------------------------------------------------------------------------------
 
208
class StaffObjLdpGenerator : public LdpGenerator
 
209
{
 
210
protected:
 
211
    ImoStaffObj* m_pObj;
 
212
 
 
213
public:
 
214
    StaffObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
215
    {
 
216
        m_pObj = dynamic_cast<ImoStaffObj*>(pImo);
 
217
    }
 
218
 
 
219
    std::string generate_source()
 
220
    {
 
221
        add_staff_num();
 
222
        source_for_base_componentobj(m_pObj);
 
223
        return m_source.str();
 
224
    }
 
225
 
 
226
protected:
 
227
 
 
228
    void add_staff_num()
 
229
    {
 
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() )
 
233
        {
 
234
            m_source << " p" << (m_pObj->get_staff() + 1);
 
235
        }
 
236
    }
 
237
 
 
238
};
 
239
 
 
240
// componentobj generator
 
241
//-------------------------------------------------------------------------------------
 
242
class ComponentObjLdpGenerator : public LdpGenerator
 
243
{
 
244
protected:
 
245
    ImoComponentObj* m_pObj;
 
246
 
 
247
public:
 
248
    ComponentObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
249
    {
 
250
        m_pObj = dynamic_cast<ImoComponentObj*>(pImo);
 
251
    }
 
252
 
 
253
    std::string generate_source()
 
254
    {
 
255
        add_visible();
 
256
        add_color();
 
257
        source_for_base_docobj(m_pObj);
 
258
        return m_source.str();
 
259
    }
 
260
 
 
261
protected:
 
262
 
 
263
    void add_visible()
 
264
    {
 
265
        if (!m_pObj->is_visible())
 
266
            m_source << " (visible no)";
 
267
    }
 
268
 
 
269
    void add_color()
 
270
    {
 
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) << ")";
 
275
    }
 
276
};
 
277
 
 
278
 
 
279
// docobj generator
 
280
//-------------------------------------------------------------------------------------
 
281
class DocObjLdpGenerator : public LdpGenerator
 
282
{
 
283
protected:
 
284
    ImoDocObj* m_pObj;
 
285
 
 
286
public:
 
287
    DocObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
288
    {
 
289
        m_pObj = dynamic_cast<ImoDocObj*>(pImo);
 
290
    }
 
291
 
 
292
    std::string generate_source()
 
293
    {
 
294
        add_user_location();
 
295
        add_attachments();
 
296
        source_for_base_imobj(m_pObj);
 
297
        return m_source.str();
 
298
    }
 
299
 
 
300
protected:
 
301
 
 
302
    void add_user_location()
 
303
    {
 
304
        Tenths ux = m_pObj->get_user_location_x();
 
305
        if (ux != 0.0f)
 
306
            m_source << " (dx " << LdpExporter::float_to_string(ux) << ")";
 
307
 
 
308
        Tenths uy = m_pObj->get_user_location_y();
 
309
        if (uy != 0.0f)
 
310
            m_source << " (dy " << LdpExporter::float_to_string(uy) << ")";
 
311
    }
 
312
 
 
313
    void add_attachments()
 
314
    {
 
315
        if (m_pObj->get_num_attachments() > 0)
 
316
        {
 
317
            increment_indent();
 
318
//            std::list<ImoAuxObj*>& attachments = m_pObj->get_attachments();
 
319
//            std::list<ImoAuxObj*>::iterator it;
 
320
//            for (it = attachments.begin(); it != attachments.end(); ++it)
 
321
//            {
 
322
//                ImoAuxObj* pAuxObj = *it;
 
323
//                if ( pAuxObj->is_relobj() )
 
324
//                {
 
325
//                    ImRelObj* pRO = dynamic_cast<ImRelObj*)>(pAuxObj);
 
326
//
 
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())
 
333
//                    {
 
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);
 
338
//                        else
 
339
//                            m_source += pRO->SourceLDP_Middle(nIndent, fUndoData, (lmNoteRest*)this);
 
340
//                    }
 
341
//                }
 
342
//                else if ( pAuxObj->IsRelObX() )
 
343
//                {
 
344
//                    lmRelObX* pRO = (lmRelObX*)pAuxObj;
 
345
//
 
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())
 
352
//                    {
 
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);
 
357
//                        else
 
358
//                            m_source += pRO->SourceLDP_Middle(nIndent, fUndoData, this);
 
359
//                    }
 
360
//                }
 
361
//                else
 
362
//                    source_for_auxobj(pAuxObj);
 
363
//            }
 
364
            decrement_indent();
 
365
        }
 
366
    }
 
367
};
 
368
 
 
369
 
 
370
// imobj generator
 
371
//-------------------------------------------------------------------------------------
 
372
class ImObjLdpGenerator : public LdpGenerator
 
373
{
 
374
protected:
 
375
    ImoObj* m_pObj;
 
376
 
 
377
public:
 
378
    ImObjLdpGenerator(ImoObj* pImo, LdpExporter* pExporter) : LdpGenerator(pExporter)
 
379
    {
 
380
        m_pObj = pImo;
 
381
    }
 
382
 
 
383
    std::string generate_source()
 
384
    {
 
385
        return m_source.str();
 
386
    }
 
387
};
 
388
 
 
389
 
 
390
 
 
391
//-------------------------------------------------------------------------------------
 
392
// LdpGenerator implementation
 
393
//-------------------------------------------------------------------------------------
 
394
 
 
395
void LdpGenerator::start_element()
 
396
{
 
397
    add_indent_spaces();
 
398
}
 
399
 
 
400
void LdpGenerator::end_element()
 
401
{
 
402
    m_source << ")";
 
403
    if (m_pExporter->get_indent() > 0)
 
404
        m_source << endl;
 
405
}
 
406
 
 
407
void LdpGenerator::add_indent_spaces()
 
408
{
 
409
    m_source.clear();
 
410
    int indent = m_pExporter->get_indent() * lml_LDP_INDENT_STEP;
 
411
    while (indent > 0)
 
412
    {
 
413
        m_source << " ";
 
414
        indent--;
 
415
    }
 
416
}
 
417
 
 
418
void LdpGenerator::add_element_name(const std::string& name, ImoObj* pImo)
 
419
{
 
420
    m_source << "(" << name;
 
421
    if (m_pExporter->get_add_id())
 
422
        m_source << "#" << std::dec << pImo->get_id();
 
423
    m_source << " ";
 
424
}
 
425
 
 
426
void LdpGenerator::add_source_for(ImoObj* pImo)
 
427
{
 
428
    m_source << m_pExporter->get_source(pImo);
 
429
}
 
430
 
 
431
void LdpGenerator::source_for_base_staffobj(ImoObj* pImo)
 
432
{
 
433
    LdpGenerator* pGen = new StaffObjLdpGenerator(pImo, m_pExporter);
 
434
    m_source << pGen->generate_source();
 
435
}
 
436
 
 
437
void LdpGenerator::source_for_base_componentobj(ImoObj* pImo)
 
438
{
 
439
    LdpGenerator* pGen = new ComponentObjLdpGenerator(pImo, m_pExporter);
 
440
    m_source << pGen->generate_source();
 
441
}
 
442
 
 
443
void LdpGenerator::source_for_base_docobj(ImoObj* pImo)
 
444
{
 
445
    LdpGenerator* pGen = new DocObjLdpGenerator(pImo, m_pExporter);
 
446
    m_source << pGen->generate_source();
 
447
}
 
448
 
 
449
void LdpGenerator::source_for_base_imobj(ImoObj* pImo)
 
450
{
 
451
    LdpGenerator* pGen = new ImObjLdpGenerator(pImo, m_pExporter);
 
452
    m_source << pGen->generate_source();
 
453
}
 
454
 
 
455
void LdpGenerator::source_for_auxobj(ImoObj* pImo)
 
456
{
 
457
    m_source <<  m_pExporter->get_source(pImo);
 
458
}
 
459
 
 
460
void LdpGenerator::increment_indent()
 
461
{
 
462
    //TODO
 
463
}
 
464
 
 
465
void LdpGenerator::decrement_indent()
 
466
{
 
467
    //TODO
 
468
}
 
469
 
 
470
 
 
471
 
 
472
//-------------------------------------------------------------------------------------
 
473
// LdpExporter implementation
 
474
//-------------------------------------------------------------------------------------
 
475
 
 
476
LdpExporter::LdpExporter()
 
477
    : m_nIndent(0)
 
478
    , m_fAddId(false)
 
479
{
 
480
}
 
481
 
 
482
LdpExporter::~LdpExporter()
 
483
{
 
484
}
 
485
 
 
486
std::string LdpExporter::get_source(ImoObj* pImo)
 
487
{
 
488
    LdpGenerator* pGen = new_generator(pImo);
 
489
    std::string source = pGen->generate_source();
 
490
    delete pGen;
 
491
    return source;
 
492
}
 
493
 
 
494
LdpGenerator* LdpExporter::new_generator(ImoObj* pImo)
 
495
{
 
496
    //factory method
 
497
 
 
498
    switch(pImo->get_obj_type())
 
499
    {
 
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);
 
530
        default:
 
531
            return new ErrorLdpGenerator(pImo, this);
 
532
    }
 
533
}
 
534
 
 
535
 
 
536
 
 
537
// static methods
 
538
 
 
539
std::string LdpExporter::clef_type_to_ldp(int clefType)
 
540
{
 
541
    //AWARE: indexes in correspondence with enum ImoClef::k__type
 
542
    static const std::string name[] = {
 
543
        "G",
 
544
        "F4",
 
545
        "F3",
 
546
        "C1",
 
547
        "C2",
 
548
        "C3",
 
549
        "C4",
 
550
        "percussion",
 
551
        "C5",
 
552
        "F5",
 
553
        "G1",
 
554
        "8_G",     //8 above
 
555
        "G_8",     //8 below
 
556
        "8_F4",    //8 above
 
557
        "F4_8",    //8 below
 
558
        "15_G3",   //15 above
 
559
        "G3_15",   //15 below
 
560
        "15_F4",   //15 above
 
561
        "F4_15",   //15 below
 
562
    };
 
563
    static const std::string undefined = "undefined";
 
564
 
 
565
 
 
566
    if (clefType == ImoClef::k_undefined)
 
567
        return undefined;
 
568
    else
 
569
        return name[clefType];
 
570
}
 
571
 
 
572
std::string LdpExporter::color_to_ldp(rgba16& color)
 
573
{
 
574
    stringstream source;
 
575
    source << "#";
 
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;
 
580
    return source.str();
 
581
}
 
582
 
 
583
std::string LdpExporter::float_to_string(float num)
 
584
{
 
585
    return "(TODO: float_to_string)";
 
586
}
 
587
 
 
588
 
 
589
 
 
590
}  //namespace lomse