~s-cecilio/lomse/master

« back to all changes in this revision

Viewing changes to src/internal_model/lomse_internal_model.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_internal_model.h"
 
22
 
 
23
#include <algorithm>
 
24
#include <math.h>                   //pow
 
25
#include "lomse_staffobjs_table.h"
 
26
#include "lomse_im_note.h"
 
27
#include "lomse_basic_objects.h"
 
28
 
 
29
using namespace std;
 
30
 
 
31
namespace lomse
 
32
{
 
33
 
 
34
 
 
35
//-------------------------------------------------------------------------------------
 
36
// ImoObj implementation
 
37
//-------------------------------------------------------------------------------------
 
38
 
 
39
ImoObj::ImoObj(int objtype, DtoObj& dto)
 
40
    : m_id( dto.get_id() )
 
41
    , m_objtype( objtype )
 
42
{
 
43
}
 
44
 
 
45
ImoObj::~ImoObj()
 
46
{
 
47
    NodeInTree<ImoObj>::children_iterator it(this);
 
48
    it = begin();
 
49
    while (it != end())
 
50
    {
 
51
        ImoObj* child = *it;
 
52
        ++it;
 
53
            delete child;
 
54
    }
 
55
}
 
56
 
 
57
void ImoObj::accept_in(BaseVisitor& v)
 
58
{
 
59
    Visitor<ImoObj>* p = dynamic_cast<Visitor<ImoObj>*>(&v);
 
60
    if (p)
 
61
    {
 
62
        p->start_visit(this);
 
63
    }
 
64
}
 
65
 
 
66
void ImoObj::accept_out(BaseVisitor& v)
 
67
{
 
68
    Visitor<ImoObj>* p = dynamic_cast<Visitor<ImoObj>*>(&v);
 
69
    if (p)
 
70
    {
 
71
        p->start_visit(this);
 
72
    }
 
73
}
 
74
 
 
75
ImoObj* ImoObj::get_child_of_type(int objtype)
 
76
{
 
77
    for (int i=0; i < get_num_children(); i++)
 
78
    {
 
79
        ImoObj* pChild = get_child(i);
 
80
        if (pChild->get_obj_type() == objtype)
 
81
            return pChild;
 
82
    }
 
83
    return NULL;
 
84
}
 
85
 
 
86
 
 
87
//-------------------------------------------------------------------------------------
 
88
// ImoBinaryRelObj implementation
 
89
//-------------------------------------------------------------------------------------
 
90
 
 
91
//ImoBinaryRelObj::ImoBinaryRelObj(ImoDocObj* pOwner, long id, int type,
 
92
//                               ImoStaffObj* pStartSO, ImoStaffObj* pEndSO)
 
93
//    : ImoRelObj(pOwner, id, type)
 
94
//    , m_pStartSO(pStartSO)
 
95
//    , m_pEndSO(pEndSO)
 
96
//{
 
97
//}
 
98
//
 
99
ImoBinaryRelObj::~ImoBinaryRelObj()
 
100
{
 
101
}
 
102
 
 
103
//void ImoBinaryRelObj::remove(ImoStaffObj* pSO)
 
104
//{
 
105
//    if (m_pStartSO == pSO)
 
106
//        m_pStartSO = (ImoStaffObj*)NULL;
 
107
//    else if (m_pEndSO == pSO)
 
108
//        m_pEndSO = (ImoStaffObj*)NULL;
 
109
//}
 
110
 
 
111
 
 
112
 
 
113
//-------------------------------------------------------------------------------------
 
114
// ImoMultiRelObj implementation
 
115
//-------------------------------------------------------------------------------------
 
116
 
 
117
//ImoMultiRelObj::ImoMultiRelObj(ImoDocObj* pOwner, long id, int type)
 
118
//    : ImoRelObj(pOwner, id, type)
 
119
//{
 
120
//}
 
121
 
 
122
ImoMultiRelObj::~ImoMultiRelObj()
 
123
{
 
124
    m_relatedObjects.clear();
 
125
}
 
126
 
 
127
//void ImoMultiRelObj::remove(ImoStaffObj* pSO)
 
128
//{
 
129
//    //remove StaffObj.
 
130
//      //AWARE: This method is always invoked by a SO. Therefore it will
 
131
//      //not inform back the SO, as this is unnecessary and causes problems when
 
132
//      //deleting the relationship object
 
133
//
 
134
//    std::list<ImoStaffObj*>::iterator it;
 
135
//    it = find(m_relatedObjects.begin(), m_relatedObjects.end(), pSO);
 
136
//    m_relatedObjects.erase(it);
 
137
//    on_relationship_modified();
 
138
//}
 
139
 
 
140
void ImoMultiRelObj::push_back(ImoStaffObj* pSO)
 
141
{
 
142
    m_relatedObjects.push_back(pSO);
 
143
    //on_relationship_modified();
 
144
}
 
145
 
 
146
//void ImoMultiRelObj::include(ImoStaffObj* pSO, int index)
 
147
//{
 
148
//    // Add a note to the relation. index is the position that the added StaffObj
 
149
//    // must occupy (0..n). If index == -1, StaffObj will be added at the end.
 
150
//
 
151
//      //add the StaffObj
 
152
//      if (index == -1 || index == get_num_objects())
 
153
//              m_relatedObjects.push_back(pSO);
 
154
//      else
 
155
//      {
 
156
//              int iN;
 
157
//              std::list<ImoStaffObj*>::iterator it;
 
158
//              for(iN=0, it=m_relatedObjects.begin(); it != m_relatedObjects.end(); ++it, iN++)
 
159
//              {
 
160
//                      if (iN == index)
 
161
//                      {
 
162
//                              //insert before current item
 
163
//                              m_relatedObjects.insert(it, pSO);
 
164
//                              break;
 
165
//                      }
 
166
//              }
 
167
//      }
 
168
//
 
169
//    on_relationship_modified();
 
170
//}
 
171
//
 
172
//int ImoMultiRelObj::get_object_index(ImoStaffObj* pSO)
 
173
//{
 
174
//      //returns the position in the StaffObjs list (0..n)
 
175
//
 
176
//      int iN;
 
177
//    std::list<ImoStaffObj*>::iterator it;
 
178
//    for(iN=0, it=m_relatedObjects.begin(); it != m_relatedObjects.end(); ++it, iN++)
 
179
//      {
 
180
//              if (pSO == *it)
 
181
//            return iN;
 
182
//      }
 
183
//      return 0;                       //compiler happy
 
184
//}
 
185
 
 
186
 
 
187
 
 
188
//-------------------------------------------------------------------------------------
 
189
// ImoComponentObj implementation
 
190
//-------------------------------------------------------------------------------------
 
191
 
 
192
ImoComponentObj::ImoComponentObj(int objtype, DtoComponentObj& dto)
 
193
    : ImoDocObj(objtype, dto)
 
194
    , m_fVisible( dto.is_visible() )
 
195
    , m_color( dto.get_color() )
 
196
{
 
197
}
 
198
 
 
199
void ImoComponentObj::set_color(rgba16 color)
 
200
{
 
201
    m_color = color;
 
202
}
 
203
 
 
204
 
 
205
//-------------------------------------------------------------------------------------
 
206
// ImoStaffObj implementation
 
207
//-------------------------------------------------------------------------------------
 
208
 
 
209
ImoStaffObj::ImoStaffObj(int objtype, DtoStaffObj& dto)
 
210
    : ImoComponentObj(objtype, dto)
 
211
    , m_staff( dto.get_staff() )
 
212
{
 
213
}
 
214
 
 
215
 
 
216
//-------------------------------------------------------------------------------------
 
217
// ImoAuxObj implementation
 
218
//-------------------------------------------------------------------------------------
 
219
 
 
220
ImoAuxObj::ImoAuxObj(int objtype, DtoAuxObj& dto)
 
221
    : ImoComponentObj(objtype, dto)
 
222
{
 
223
}
 
224
 
 
225
 
 
226
//-------------------------------------------------------------------------------------
 
227
// ImoBarline implementation
 
228
//-------------------------------------------------------------------------------------
 
229
 
 
230
ImoBarline::ImoBarline(DtoBarline& dto, long id)
 
231
    : ImoStaffObj(ImoObj::k_barline, dto)
 
232
    , m_type( dto.get_barline_type() )
 
233
{
 
234
    set_id(id);
 
235
}
 
236
 
 
237
 
 
238
 
 
239
//-------------------------------------------------------------------------------------
 
240
// ImoBeamInfo implementation
 
241
//-------------------------------------------------------------------------------------
 
242
 
 
243
ImoBeamInfo::ImoBeamInfo()
 
244
    : ImoSimpleObj(ImoObj::k_beam_info)
 
245
    , m_beamNum(0)
 
246
    , m_pBeamElm(NULL)
 
247
    , m_pNR(NULL)
 
248
{
 
249
    for (int level=0; level < 6; level++)
 
250
    {
 
251
        m_beamType[level] = ImoBeam::k_none;
 
252
        m_repeat[level] = false;
 
253
    }
 
254
}
 
255
 
 
256
ImoBeamInfo::ImoBeamInfo(LdpElement* pBeamElm)
 
257
    : ImoSimpleObj(ImoObj::k_beam_info)
 
258
    , m_beamNum(0)
 
259
    , m_pBeamElm(pBeamElm)
 
260
    , m_pNR(NULL)
 
261
{
 
262
    for (int level=0; level < 6; level++)
 
263
    {
 
264
        m_beamType[level] = ImoBeam::k_none;
 
265
        m_repeat[level] = false;
 
266
    }
 
267
}
 
268
 
 
269
int ImoBeamInfo::get_line_number()
 
270
{
 
271
    if (m_pBeamElm)
 
272
        return m_pBeamElm->get_line_number();
 
273
    else
 
274
        return 0;
 
275
}
 
276
 
 
277
void ImoBeamInfo::set_beam_type(int level, int type)
 
278
{
 
279
    m_beamType[level] = type;
 
280
}
 
281
 
 
282
int ImoBeamInfo::get_beam_type(int level)
 
283
{
 
284
    return m_beamType[level];
 
285
}
 
286
 
 
287
bool ImoBeamInfo::is_end_of_beam()
 
288
{
 
289
    for (int level=0; level < 6; level++)
 
290
    {
 
291
        if (m_beamType[level] == ImoBeam::k_begin
 
292
            || m_beamType[level] == ImoBeam::k_forward
 
293
            || m_beamType[level] == ImoBeam::k_continue
 
294
            )
 
295
            return false;
 
296
    }
 
297
    return true;
 
298
}
 
299
 
 
300
void ImoBeamInfo::set_repeat(int level, bool value)
 
301
{
 
302
    m_repeat[level] = value;
 
303
}
 
304
 
 
305
bool ImoBeamInfo::get_repeat(int level)
 
306
{
 
307
    return m_repeat[level];
 
308
}
 
309
 
 
310
 
 
311
//-------------------------------------------------------------------------------------
 
312
// ImoClef implementation
 
313
//-------------------------------------------------------------------------------------
 
314
 
 
315
ImoClef::ImoClef(DtoClef& dto)
 
316
    : ImoStaffObj(ImoObj::k_clef, dto)
 
317
    , m_clefType( dto.get_clef_type() )
 
318
{
 
319
}
 
320
 
 
321
ImoClef::ImoClef(int clefType)
 
322
    : ImoStaffObj(ImoObj::k_clef)
 
323
    , m_clefType(clefType)
 
324
{
 
325
}
 
326
 
 
327
 
 
328
 
 
329
//-------------------------------------------------------------------------------------
 
330
// ImoColorDto implementation
 
331
//-------------------------------------------------------------------------------------
 
332
 
 
333
ImoColorDto::ImoColorDto(int16u r, int16u g, int16u b, int16u a)
 
334
    : ImoSimpleObj(ImoObj::k_color_info)
 
335
    , m_color(r, g, b, a)
 
336
    , m_ok(true)
 
337
{
 
338
}
 
339
 
 
340
int16u ImoColorDto::convert_from_hex(const std::string& hex)
 
341
{
 
342
    int value = 0;
 
343
 
 
344
    int a = 0;
 
345
    int b = static_cast<int>(hex.length()) - 1;
 
346
    for (; b >= 0; a++, b--)
 
347
    {
 
348
        if (hex[b] >= '0' && hex[b] <= '9')
 
349
        {
 
350
            value += (hex[b] - '0') * (1 << (a * 4));
 
351
        }
 
352
        else
 
353
        {
 
354
            switch (hex[b])
 
355
            {
 
356
                case 'A':
 
357
                case 'a':
 
358
                    value += 10 * (1 << (a * 4));
 
359
                    break;
 
360
 
 
361
                case 'B':
 
362
                case 'b':
 
363
                    value += 11 * (1 << (a * 4));
 
364
                    break;
 
365
 
 
366
                case 'C':
 
367
                case 'c':
 
368
                    value += 12 * (1 << (a * 4));
 
369
                    break;
 
370
 
 
371
                case 'D':
 
372
                case 'd':
 
373
                    value += 13 * (1 << (a * 4));
 
374
                    break;
 
375
 
 
376
                case 'E':
 
377
                case 'e':
 
378
                    value += 14 * (1 << (a * 4));
 
379
                    break;
 
380
 
 
381
                case 'F':
 
382
                case 'f':
 
383
                    value += 15 * (1 << (a * 4));
 
384
                    break;
 
385
 
 
386
                default:
 
387
                    m_ok = false;
 
388
                    //cout << "Error: invalid character '" << hex[b] << "' in hex number" << endl;
 
389
                    break;
 
390
            }
 
391
        }
 
392
    }
 
393
 
 
394
    return static_cast<int16u>(value);
 
395
}
 
396
 
 
397
rgba16& ImoColorDto::get_from_rgb_string(const std::string& rgb)
 
398
{
 
399
    m_ok = true;
 
400
 
 
401
    if (rgb[0] == '#')
 
402
    {
 
403
        m_color.r = convert_from_hex( rgb.substr(1, 2) );
 
404
        m_color.g = convert_from_hex( rgb.substr(3, 2) );
 
405
        m_color.b = convert_from_hex( rgb.substr(5, 2) );
 
406
        m_color.a = 255;
 
407
    }
 
408
 
 
409
    if (!m_ok)
 
410
        m_color = rgba16(0,0,0,255);
 
411
 
 
412
    return m_color;
 
413
}
 
414
 
 
415
rgba16& ImoColorDto::get_from_rgba_string(const std::string& rgba)
 
416
{
 
417
    m_ok = true;
 
418
 
 
419
    if (rgba[0] == '#')
 
420
    {
 
421
        m_color.r = convert_from_hex( rgba.substr(1, 2) );
 
422
        m_color.g = convert_from_hex( rgba.substr(3, 2) );
 
423
        m_color.b = convert_from_hex( rgba.substr(5, 2) );
 
424
        m_color.a = convert_from_hex( rgba.substr(7, 2) );
 
425
    }
 
426
 
 
427
    if (!m_ok)
 
428
        m_color = rgba16(0,0,0,255);
 
429
 
 
430
    return m_color;
 
431
}
 
432
 
 
433
rgba16& ImoColorDto::get_from_string(const std::string& hex)
 
434
{
 
435
    if (hex.length() == 7)
 
436
        return get_from_rgb_string(hex);
 
437
    else if (hex.length() == 9)
 
438
        return get_from_rgba_string(hex);
 
439
    else
 
440
    {
 
441
        m_ok = false;
 
442
        m_color = rgba16(0,0,0,255);
 
443
        return m_color;
 
444
    }
 
445
}
 
446
 
 
447
 
 
448
//-------------------------------------------------------------------------------------
 
449
// ImoContent implementation
 
450
//-------------------------------------------------------------------------------------
 
451
 
 
452
 
 
453
//-------------------------------------------------------------------------------------
 
454
// ImoDocObj implementation
 
455
//-------------------------------------------------------------------------------------
 
456
 
 
457
ImoDocObj::ImoDocObj(int objtype)
 
458
    : ImoObj(objtype)
 
459
    , m_txUserLocation(0.0f)
 
460
    , m_tyUserLocation(0.0f)
 
461
{
 
462
}
 
463
 
 
464
ImoDocObj::ImoDocObj(long id, int objtype)
 
465
    : ImoObj(id, objtype)
 
466
    , m_txUserLocation(0.0f)
 
467
    , m_tyUserLocation(0.0f)
 
468
{
 
469
}
 
470
 
 
471
ImoDocObj::ImoDocObj(int objtype, DtoDocObj& dto)
 
472
    : ImoObj(objtype, dto)
 
473
    , m_txUserLocation( dto.get_user_location_x() )
 
474
    , m_tyUserLocation( dto.get_user_location_y() )
 
475
{
 
476
}
 
477
 
 
478
ImoDocObj::~ImoDocObj()
 
479
{
 
480
}
 
481
 
 
482
void ImoDocObj::attach(ImoAuxObj* pAO)
 
483
{
 
484
    ImoAttachments* pAttachments = get_attachments();
 
485
    if (!pAttachments)
 
486
    {
 
487
        pAttachments = new ImoAttachments();
 
488
        append_child(pAttachments);
 
489
    }
 
490
    pAttachments->append_child(pAO);
 
491
}
 
492
 
 
493
ImoAuxObj* ImoDocObj::get_attachment(int i)
 
494
{
 
495
    ImoAttachments* pAttachments = get_attachments();
 
496
    ImoObj* pImo = pAttachments->get_child(i);
 
497
    return dynamic_cast<ImoAuxObj*>( pImo );
 
498
}
 
499
 
 
500
bool ImoDocObj::has_attachments()
 
501
{
 
502
    ImoAttachments* pAttachments = get_attachments();
 
503
    if (pAttachments)
 
504
        return pAttachments->get_num_items() > 0;
 
505
    else
 
506
        return false;
 
507
}
 
508
 
 
509
int ImoDocObj::get_num_attachments()
 
510
{
 
511
    ImoAttachments* pAttachments = get_attachments();
 
512
    if (pAttachments)
 
513
        return pAttachments->get_num_items();
 
514
    else
 
515
        return 0;
 
516
}
 
517
 
 
518
ImoAttachments* ImoDocObj::get_attachments()
 
519
{
 
520
    return dynamic_cast<ImoAttachments*>( get_child_of_type(ImoObj::k_attachments) );
 
521
}
 
522
 
 
523
//-------------------------------------------------------------------------------------
 
524
// ImoDocument implementation
 
525
//-------------------------------------------------------------------------------------
 
526
 
 
527
int ImoDocument::get_num_content_items()
 
528
{
 
529
    if (has_children())
 
530
    {
 
531
        ImoObj* pChild = get_first_child();
 
532
        int num = pChild->get_num_children();
 
533
        return num;
 
534
    }
 
535
    else
 
536
        return 0;
 
537
}
 
538
 
 
539
ImoDocObj* ImoDocument::get_content_item(int iItem)
 
540
{
 
541
    ImoContent* pContent = get_content();
 
542
    if (iItem < pContent->get_num_children())
 
543
        return dynamic_cast<ImoDocObj*>( pContent->get_child(iItem) );
 
544
    else
 
545
        return NULL;
 
546
}
 
547
 
 
548
ImoContent* ImoDocument::get_content()
 
549
{
 
550
    return dynamic_cast<ImoContent*>( get_first_child() );
 
551
}
 
552
 
 
553
 
 
554
//-------------------------------------------------------------------------------------
 
555
// ImoFermata implementation
 
556
//-------------------------------------------------------------------------------------
 
557
 
 
558
ImoFermata::ImoFermata(DtoFermata& dto)
 
559
    : ImoAuxObj(ImoObj::k_fermata, dto)
 
560
    , m_placement( dto.get_placement() )
 
561
    , m_symbol( dto.get_symbol() )
 
562
{
 
563
}
 
564
 
 
565
 
 
566
//-------------------------------------------------------------------------------------
 
567
// ImoGoBackFwd implementation
 
568
//-------------------------------------------------------------------------------------
 
569
 
 
570
ImoGoBackFwd::ImoGoBackFwd(DtoGoBackFwd& dto)
 
571
    : ImoStaffObj(ImoObj::k_go_back_fwd, dto)
 
572
    , m_fFwd( dto.is_forward() )
 
573
    , m_rTimeShift( dto.get_time_shift() )
 
574
    , SHIFT_START_END(100000000.0f)
 
575
{
 
576
}
 
577
 
 
578
 
 
579
//-------------------------------------------------------------------------------------
 
580
// ImoInstrument implementation
 
581
//-------------------------------------------------------------------------------------
 
582
 
 
583
ImoInstrument::ImoInstrument()
 
584
    : ImoContainerObj(ImoObj::k_instrument)
 
585
    , m_numStaves(1)
 
586
    , m_name("")
 
587
    , m_abbrev("")
 
588
    , m_midi()
 
589
    , m_pGroup(NULL)
 
590
{
 
591
//      m_midiChannel = g_pMidi->DefaultVoiceChannel();
 
592
//      m_midiInstr = g_pMidi->DefaultVoiceInstr();
 
593
}
 
594
 
 
595
ImoInstrument::~ImoInstrument()
 
596
{
 
597
}
 
598
 
 
599
void ImoInstrument::set_name(ImoScoreText* pText)
 
600
{
 
601
    m_name = *pText;
 
602
    delete pText;
 
603
}
 
604
 
 
605
void ImoInstrument::set_abbrev(ImoScoreText* pText)
 
606
{
 
607
    m_abbrev = *pText;
 
608
    delete pText;
 
609
}
 
610
 
 
611
void ImoInstrument::set_midi_info(ImoMidiInfo* pInfo)
 
612
{
 
613
    m_midi = *pInfo;
 
614
    delete pInfo;
 
615
}
 
616
 
 
617
ImoMusicData* ImoInstrument::get_musicdata()
 
618
{
 
619
    return dynamic_cast<ImoMusicData*>( get_child_of_type(ImoObj::k_music_data) );
 
620
}
 
621
 
 
622
 
 
623
//-------------------------------------------------------------------------------------
 
624
// ImoInstrGroup implementation
 
625
//-------------------------------------------------------------------------------------
 
626
 
 
627
ImoInstrGroup::ImoInstrGroup()
 
628
    : ImoSimpleObj(ImoObj::k_instr_group)
 
629
    , m_fJoinBarlines(true)
 
630
    , m_symbol(k_brace)
 
631
    , m_name("")
 
632
    , m_abbrev("")
 
633
{
 
634
}
 
635
 
 
636
ImoInstrGroup::~ImoInstrGroup()
 
637
{
 
638
    m_instruments.clear();
 
639
}
 
640
 
 
641
void ImoInstrGroup::set_name(ImoScoreText* pText)
 
642
{
 
643
    m_name = *pText;
 
644
    delete pText;
 
645
}
 
646
 
 
647
void ImoInstrGroup::set_abbrev(ImoScoreText* pText)
 
648
{
 
649
    m_abbrev = *pText;
 
650
    delete pText;
 
651
}
 
652
 
 
653
ImoInstrument* ImoInstrGroup::get_instrument(int iInstr)    //iInstr = 0..n-1
 
654
{
 
655
    std::list<ImoInstrument*>::iterator it;
 
656
    int i = 0;
 
657
    for (it = m_instruments.begin(); it != m_instruments.end() && i < iInstr; ++it, ++i);
 
658
    if (i == iInstr)
 
659
        return *it;
 
660
    else
 
661
        return NULL;
 
662
}
 
663
 
 
664
void ImoInstrGroup::add_instrument(ImoInstrument* pInstr)
 
665
{
 
666
    m_instruments.push_back(pInstr);
 
667
    pInstr->set_in_group(this);
 
668
}
 
669
 
 
670
int ImoInstrGroup::get_num_instruments()
 
671
{
 
672
    return static_cast<int>( m_instruments.size() );
 
673
}
 
674
 
 
675
 
 
676
 
 
677
//-------------------------------------------------------------------------------------
 
678
// ImoKeySignature implementation
 
679
//-------------------------------------------------------------------------------------
 
680
 
 
681
ImoKeySignature::ImoKeySignature(DtoKeySignature& dto)
 
682
    : ImoStaffObj(ImoObj::k_key_signature, dto)
 
683
    , m_keyType( dto.get_key_type() )
 
684
{
 
685
}
 
686
 
 
687
//-------------------------------------------------------------------------------------
 
688
// ImoLine implementation
 
689
//-------------------------------------------------------------------------------------
 
690
 
 
691
ImoLine::ImoLine(ImoLineInfo& info)
 
692
    : ImoAuxObj(ImoObj::k_line)
 
693
    , m_lineInfo(info)
 
694
{
 
695
}
 
696
 
 
697
//-------------------------------------------------------------------------------------
 
698
// ImoMetronomeMark implementation
 
699
//-------------------------------------------------------------------------------------
 
700
 
 
701
ImoMetronomeMark::ImoMetronomeMark(DtoMetronomeMark& dto)
 
702
    : ImoStaffObj(ImoObj::k_metronome_mark, dto)
 
703
    , m_markType( dto.get_mark_type() )
 
704
    , m_ticksPerMinute( dto.get_ticks_per_minute() )
 
705
    , m_leftNoteType( dto.get_left_note_type() )
 
706
    , m_leftDots( dto.get_left_dots() )
 
707
    , m_rightNoteType( dto.get_right_note_type() )
 
708
    , m_rightDots( dto.get_right_dots() )
 
709
    , m_fParenthesis( dto.has_parenthesis() )
 
710
{
 
711
}
 
712
 
 
713
//-------------------------------------------------------------------------------------
 
714
// ImoMidiInfo implementation
 
715
//-------------------------------------------------------------------------------------
 
716
 
 
717
ImoMidiInfo::ImoMidiInfo()
 
718
    : ImoSimpleObj(ImoObj::k_midi_info)
 
719
    , m_instr(0)
 
720
    , m_channel(0)
 
721
{
 
722
}
 
723
 
 
724
ImoMidiInfo::ImoMidiInfo(ImoMidiInfo& dto)
 
725
    : ImoSimpleObj(ImoObj::k_midi_info)
 
726
    , m_instr( dto.get_instrument() )
 
727
    , m_channel( dto.get_channel() )
 
728
{
 
729
}
 
730
 
 
731
//-------------------------------------------------------------------------------------
 
732
// ImoScore implementation
 
733
//-------------------------------------------------------------------------------------
 
734
 
 
735
ImoScore::ImoScore()
 
736
    : ImoContainerObj(ImoObj::k_score)
 
737
    , m_version("")
 
738
    , m_pColStaffObjs(NULL)
 
739
    , m_systemInfoFirst()
 
740
    , m_systemInfoOther()
 
741
    , m_pageInfo()
 
742
{
 
743
    append_child( new ImoInstruments() );
 
744
    append_child( new ImoOptions() );
 
745
}
 
746
 
 
747
ImoScore::~ImoScore()
 
748
{
 
749
    delete_staffobjs_collection();
 
750
    delete_text_styles();
 
751
}
 
752
 
 
753
void ImoScore::delete_staffobjs_collection()
 
754
{
 
755
    if (m_pColStaffObjs)
 
756
        delete m_pColStaffObjs;
 
757
}
 
758
 
 
759
void ImoScore::delete_text_styles()
 
760
{
 
761
    map<std::string, ImoTextStyleInfo*>::const_iterator it;
 
762
    for (it = m_nameToStyle.begin(); it != m_nameToStyle.end(); ++it)
 
763
        delete it->second;
 
764
 
 
765
    m_nameToStyle.clear();
 
766
}
 
767
 
 
768
ImoInstruments* ImoScore::get_instruments()
 
769
{
 
770
    return dynamic_cast<ImoInstruments*>( get_child_of_type(ImoObj::k_instruments) );
 
771
}
 
772
 
 
773
ImoInstrument* ImoScore::get_instrument(int iInstr)    //iInstr = 0..n-1
 
774
{
 
775
    ImoInstruments* pColInstr = get_instruments();
 
776
    return dynamic_cast<ImoInstrument*>( pColInstr->get_child(iInstr) );
 
777
}
 
778
 
 
779
void ImoScore::add_instrument(ImoInstrument* pInstr)
 
780
{
 
781
    ImoInstruments* pColInstr = get_instruments();
 
782
    return pColInstr->append_child(pInstr);
 
783
}
 
784
 
 
785
int ImoScore::get_num_instruments()
 
786
{
 
787
    ImoInstruments* pColInstr = get_instruments();
 
788
    return pColInstr->get_num_children();
 
789
}
 
790
 
 
791
ImoOptionInfo* ImoScore::get_option(const std::string& name)
 
792
{
 
793
    ImoOptions* pColOpts = get_options();
 
794
    ImoObj::children_iterator it;
 
795
    for (it= pColOpts->begin(); it != pColOpts->end(); ++it)
 
796
    {
 
797
        ImoOptionInfo* pOpt = dynamic_cast<ImoOptionInfo*>(*it);
 
798
        if (pOpt->get_name() == name)
 
799
            return pOpt;
 
800
    }
 
801
    return NULL;
 
802
}
 
803
 
 
804
ImoOptions* ImoScore::get_options()
 
805
{
 
806
    return dynamic_cast<ImoOptions*>( get_child_of_type(ImoObj::k_options) );
 
807
}
 
808
 
 
809
void ImoScore::add_option(ImoOptionInfo* pOpt)
 
810
{
 
811
    ImoOptions* pColOpts = get_options();
 
812
    return pColOpts->append_child(pOpt);
 
813
}
 
814
 
 
815
bool ImoScore::has_options()
 
816
{
 
817
    ImoOptions* pColOpts = get_options();
 
818
    return pColOpts->get_num_children() > 0;
 
819
}
 
820
 
 
821
void ImoScore::add_sytem_info(ImoSystemInfo* pSL)
 
822
{
 
823
    if (pSL->is_first())
 
824
        m_systemInfoFirst = *pSL;
 
825
    else
 
826
        m_systemInfoOther = *pSL;
 
827
}
 
828
 
 
829
void ImoScore::add_page_info(ImoPageInfo* pPI)
 
830
{
 
831
    m_pageInfo = *pPI;
 
832
}
 
833
 
 
834
ImoInstrGroups* ImoScore::get_instrument_groups()
 
835
{
 
836
    return dynamic_cast<ImoInstrGroups*>( get_child_of_type(ImoObj::k_instrument_groups) );
 
837
}
 
838
 
 
839
void ImoScore::add_instruments_group(ImoInstrGroup* pGroup)
 
840
{
 
841
    ImoInstrGroups* pGroups = get_instrument_groups();
 
842
    if (!pGroups)
 
843
    {
 
844
        pGroups = new ImoInstrGroups();
 
845
        append_child(pGroups);
 
846
    }
 
847
    pGroups->append_child(pGroup);
 
848
 
 
849
    for (int i=0; i < pGroup->get_num_instruments(); i++)
 
850
        add_instrument(pGroup->get_instrument(i));
 
851
}
 
852
 
 
853
void ImoScore::add_title(ImoScoreTitle* pTitle)
 
854
{
 
855
    m_titles.push_back(pTitle);
 
856
    append_child(pTitle);
 
857
}
 
858
 
 
859
void ImoScore::add_style_info(ImoTextStyleInfo* pStyle)
 
860
{
 
861
    m_nameToStyle[pStyle->get_name()] = pStyle;
 
862
}
 
863
 
 
864
ImoTextStyleInfo* ImoScore::get_style_info(const std::string& name) 
 
865
{
 
866
        map<std::string, ImoTextStyleInfo*>::const_iterator it
 
867
        = m_nameToStyle.find(name);
 
868
        if (it != m_nameToStyle.end())
 
869
                return it->second;
 
870
    else
 
871
        return NULL;
 
872
}
 
873
 
 
874
ImoTextStyleInfo* ImoScore::get_default_style_info()
 
875
{
 
876
    ImoTextStyleInfo* pStyle = get_style_info("Default style");
 
877
    if (pStyle)
 
878
                return pStyle;
 
879
    else
 
880
        return create_default_style();
 
881
}
 
882
 
 
883
ImoTextStyleInfo* ImoScore::create_default_style()
 
884
{
 
885
        ImoTextStyleInfo* pStyle = new ImoTextStyleInfo();
 
886
        pStyle->set_name("Default style");
 
887
    pStyle->set_color( rgba16(0,0,0,255) );
 
888
    pStyle->set_font_name("Times New Roman");
 
889
    pStyle->set_font_size(10);
 
890
    pStyle->set_font_style(ImoFontInfo::k_normal);
 
891
    pStyle->set_font_weight(ImoFontInfo::k_normal);
 
892
    m_nameToStyle["Default style"] = pStyle;
 
893
    return pStyle;
 
894
}
 
895
 
 
896
 
 
897
//-------------------------------------------------------------------------------------
 
898
// ImoPageInfo implementation
 
899
//-------------------------------------------------------------------------------------
 
900
 
 
901
ImoPageInfo::ImoPageInfo()
 
902
    : ImoSimpleObj(ImoObj::k_page_info)
 
903
    , m_uLeftMargin(2000.0f)
 
904
    , m_uRightMargin(1500.0f)
 
905
    , m_uTopMargin(2000.0f)
 
906
    , m_uBottomMargin(2000.0f)
 
907
    , m_uBindingMargin(0.0f)
 
908
    , m_uPageSize(21000.0f, 29700.0f)
 
909
    , m_fPortrait(true)
 
910
{
 
911
    //defaults: DIN A4 (210.0 x 297.0 mm), portrait
 
912
}
 
913
 
 
914
ImoPageInfo::ImoPageInfo(ImoPageInfo& dto)
 
915
    : ImoSimpleObj(ImoObj::k_page_info)
 
916
    , m_uLeftMargin( dto.get_left_margin() )
 
917
    , m_uRightMargin( dto.get_right_margin() )
 
918
    , m_uTopMargin( dto.get_top_margin() )
 
919
    , m_uBottomMargin( dto.get_bottom_margin() )
 
920
    , m_uBindingMargin( dto.get_binding_margin() )
 
921
    , m_uPageSize( dto.get_page_size() )
 
922
    , m_fPortrait( dto.is_portrait() )
 
923
{
 
924
}
 
925
 
 
926
//-------------------------------------------------------------------------------------
 
927
// ImoSpacer implementation
 
928
//-------------------------------------------------------------------------------------
 
929
 
 
930
ImoSpacer::ImoSpacer(DtoSpacer& dto)
 
931
    : ImoStaffObj(ImoObj::k_spacer, dto)
 
932
    , m_space( dto.get_width() )
 
933
{
 
934
}
 
935
 
 
936
//-------------------------------------------------------------------------------------
 
937
// ImoSystemInfo implementation
 
938
//-------------------------------------------------------------------------------------
 
939
 
 
940
ImoSystemInfo::ImoSystemInfo()
 
941
    : ImoSimpleObj(ImoObj::k_system_info)
 
942
    , m_fFirst(true)
 
943
    , m_leftMargin(0.0f)
 
944
    , m_rightMargin(0.0f)
 
945
    , m_systemDistance(0.0f)
 
946
    , m_topSystemDistance(0.0f)
 
947
{
 
948
}
 
949
 
 
950
ImoSystemInfo::ImoSystemInfo(ImoSystemInfo& dto)
 
951
    : ImoSimpleObj(ImoObj::k_system_info)
 
952
    , m_fFirst( dto.is_first() )
 
953
    , m_leftMargin( dto.get_left_margin() )
 
954
    , m_rightMargin( dto.get_right_margin() )
 
955
    , m_systemDistance( dto.get_system_distance() )
 
956
    , m_topSystemDistance( dto.get_top_system_distance() )
 
957
{
 
958
}
 
959
 
 
960
//-------------------------------------------------------------------------------------
 
961
// ImoTextInfo implementation
 
962
//-------------------------------------------------------------------------------------
 
963
 
 
964
const std::string& ImoTextInfo::get_font_name() 
 
965
 
966
    return m_pStyle->get_font_name(); 
 
967
}
 
968
 
 
969
int ImoTextInfo::get_font_size()
 
970
 
 
971
 
972
    return m_pStyle->get_font_size(); 
 
973
}
 
974
 
 
975
int ImoTextInfo::get_font_style()
 
976
 
977
    return m_pStyle->get_font_style(); 
 
978
}
 
979
 
 
980
int ImoTextInfo::get_font_weight()
 
981
 
982
    return m_pStyle->get_font_weight(); 
 
983
}
 
984
 
 
985
rgba16 ImoTextInfo::get_color()
 
986
 
987
    return m_pStyle->get_color(); 
 
988
}
 
989
 
 
990
 
 
991
//-------------------------------------------------------------------------------------
 
992
// ImoTie implementation
 
993
//-------------------------------------------------------------------------------------
 
994
 
 
995
ImoTie::~ImoTie()
 
996
{
 
997
    if (m_pStartBezier)
 
998
        delete m_pStartBezier;
 
999
    if (m_pEndBezier)
 
1000
        delete m_pEndBezier;
 
1001
}
 
1002
 
 
1003
 
 
1004
//-------------------------------------------------------------------------------------
 
1005
// ImoTieDto implementation
 
1006
//-------------------------------------------------------------------------------------
 
1007
 
 
1008
ImoTieDto::~ImoTieDto()
 
1009
{
 
1010
    if (m_pBezier)
 
1011
        delete m_pBezier;
 
1012
}
 
1013
 
 
1014
int ImoTieDto::get_line_number()
 
1015
{
 
1016
    if (m_pTieElm)
 
1017
        return m_pTieElm->get_line_number();
 
1018
    else
 
1019
        return 0;
 
1020
}
 
1021
 
 
1022
 
 
1023
//-------------------------------------------------------------------------------------
 
1024
// ImoTimeSignature implementation
 
1025
//-------------------------------------------------------------------------------------
 
1026
 
 
1027
ImoTimeSignature::ImoTimeSignature(DtoTimeSignature& dto)
 
1028
    : ImoStaffObj(ImoObj::k_time_signature, dto)
 
1029
    , m_beats( dto.get_beats() )
 
1030
    , m_beatType( dto.get_beat_type() )
 
1031
{
 
1032
}
 
1033
 
 
1034
 
 
1035
//-------------------------------------------------------------------------------------
 
1036
// ImoTupletDto implementation
 
1037
//-------------------------------------------------------------------------------------
 
1038
 
 
1039
ImoTupletDto::ImoTupletDto()
 
1040
    : ImoSimpleObj(ImoObj::k_tuplet_info)
 
1041
    , m_fStartOfTuplet(true)
 
1042
    , m_nActualNum(0)
 
1043
    , m_nNormalNum(0)
 
1044
    , m_fShowBracket(true)
 
1045
    , m_fShowNumber(true)
 
1046
    , m_nPlacement(k_default)
 
1047
    , m_pTupletElm(NULL)
 
1048
    , m_pNR(NULL)
 
1049
{
 
1050
}
 
1051
 
 
1052
ImoTupletDto::ImoTupletDto(LdpElement* pTupletElm)
 
1053
    : ImoSimpleObj(ImoObj::k_tuplet_info)
 
1054
    , m_fStartOfTuplet(true)
 
1055
    , m_nActualNum(0)
 
1056
    , m_nNormalNum(0)
 
1057
    , m_fShowBracket(true)
 
1058
    , m_fShowNumber(true)
 
1059
    , m_nPlacement(k_default)
 
1060
    , m_pTupletElm(pTupletElm)
 
1061
    , m_pNR(NULL)
 
1062
{
 
1063
}
 
1064
 
 
1065
int ImoTupletDto::get_line_number()
 
1066
{
 
1067
    if (m_pTupletElm)
 
1068
        return m_pTupletElm->get_line_number();
 
1069
    else
 
1070
        return 0;
 
1071
}
 
1072
 
 
1073
 
 
1074
//-------------------------------------------------------------------------------------
 
1075
// global functions related to notes
 
1076
//-------------------------------------------------------------------------------------
 
1077
 
 
1078
int to_step(const char& letter)
 
1079
{
 
1080
        switch (letter)
 
1081
    {
 
1082
                case 'a':       return ImoNote::A;
 
1083
                case 'b':       return ImoNote::B;
 
1084
                case 'c':       return ImoNote::C;
 
1085
                case 'd':       return ImoNote::D;
 
1086
                case 'e':       return ImoNote::E;
 
1087
                case 'f':       return ImoNote::F;
 
1088
                case 'g':       return ImoNote::G;
 
1089
        }
 
1090
        return -1;
 
1091
}
 
1092
 
 
1093
int to_octave(const char& letter)
 
1094
{
 
1095
        switch (letter)
 
1096
    {
 
1097
                case '0':       return 0;
 
1098
                case '1':       return 1;
 
1099
                case '2':       return 2;
 
1100
                case '3':       return 3;
 
1101
                case '4':       return 4;
 
1102
                case '5':       return 5;
 
1103
                case '6':       return 6;
 
1104
                case '7':       return 7;
 
1105
                case '8':       return 8;
 
1106
                case '9':       return 9;
 
1107
        }
 
1108
        return -1;
 
1109
}
 
1110
 
 
1111
int to_accidentals(const std::string& accidentals)
 
1112
{
 
1113
    switch (accidentals.length())
 
1114
    {
 
1115
        case 0:
 
1116
            return ImoNote::k_no_accidentals;
 
1117
            break;
 
1118
 
 
1119
        case 1:
 
1120
            if (accidentals[0] == '+')
 
1121
                return ImoNote::k_sharp;
 
1122
            else if (accidentals[0] == '-')
 
1123
                return ImoNote::k_flap;
 
1124
            else if (accidentals[0] == '=')
 
1125
                return ImoNote::k_natural;
 
1126
            else if (accidentals[0] == 'x')
 
1127
                return ImoNote::k_double_sharp;
 
1128
            else
 
1129
                return -1;
 
1130
            break;
 
1131
 
 
1132
        case 2:
 
1133
            if (accidentals.compare(0, 2, "++"))
 
1134
                return ImoNote::k_sharp_sharp;
 
1135
            else if (accidentals.compare(0, 2, "--"))
 
1136
                return ImoNote::k_flat_flat;
 
1137
            else if (accidentals.compare(0, 2, "=-"))
 
1138
                return ImoNote::k_natural_flat;
 
1139
            else
 
1140
                return -1;
 
1141
            break;
 
1142
 
 
1143
        default:
 
1144
            return -1;
 
1145
    }
 
1146
}
 
1147
 
 
1148
int to_note_type(const char& letter)
 
1149
{
 
1150
    //  USA           UK                      ESP               LDP     NoteType
 
1151
    //  -----------   --------------------    -------------     ---     ---------
 
1152
    //  long          longa                   longa             l       k_longa = 0
 
1153
    //  double whole  breve                   cuadrada, breve   b       k_breve = 1
 
1154
    //  whole         semibreve               redonda           w       k_whole = 2
 
1155
    //  half          minim                   blanca            h       k_half = 3
 
1156
    //  quarter       crochet                 negra             q       k_quarter = 4
 
1157
    //  eighth        quaver                  corchea           e       k_eighth = 5
 
1158
    //  sixteenth     semiquaver              semicorchea       s       k_16th = 6
 
1159
    //  32nd          demisemiquaver          fusa              t       k_32th = 7
 
1160
    //  64th          hemidemisemiquaver      semifusa          i       k_64th = 8
 
1161
    //  128th         semihemidemisemiquaver  garrapatea        o       k_128th = 9
 
1162
    //  256th         ???                     semigarrapatea    f       k_256th = 10
 
1163
 
 
1164
    switch (letter)
 
1165
    {
 
1166
        case 'l':     return ImoNote::k_longa;
 
1167
        case 'b':     return ImoNote::k_breve;
 
1168
        case 'w':     return ImoNote::k_whole;
 
1169
        case 'h':     return ImoNote::k_half;
 
1170
        case 'q':     return ImoNote::k_quarter;
 
1171
        case 'e':     return ImoNote::k_eighth;
 
1172
        case 's':     return ImoNote::k_16th;
 
1173
        case 't':     return ImoNote::k_32th;
 
1174
        case 'i':     return ImoNote::k_64th;
 
1175
        case 'o':     return ImoNote::k_128th;
 
1176
        case 'f':     return ImoNote::k_256th;
 
1177
        default:
 
1178
            return -1;
 
1179
    }
 
1180
}
 
1181
 
 
1182
bool ldp_pitch_to_components(const string& pitch, int *step, int* octave, int* accidentals)
 
1183
{
 
1184
    //    Analyzes string pitch (LDP format), extracts its parts (step, octave and
 
1185
    //    accidentals) and stores them in the corresponding parameters.
 
1186
    //    Returns true if error (pitch is not a valid pitch name)
 
1187
    //
 
1188
    //    In LDP pitch is represented as a combination of the step of the diatonic scale, the
 
1189
    //    chromatic alteration, and the octave.
 
1190
    //      - The accidentals parameter represents chromatic alteration (does not include tonal
 
1191
    //        key alterations)
 
1192
    //      - The octave element is represented by the numbers 0 to 9, where 4 indicates
 
1193
    //        the octave started by middle C.
 
1194
    //
 
1195
    //    pitch must be trimed (no spaces before or after real data) and lower case
 
1196
 
 
1197
    size_t i = pitch.length() - 1;
 
1198
    if (i < 1)
 
1199
        return true;   //error
 
1200
 
 
1201
    *octave = to_octave(pitch[i--]);
 
1202
    if (*step == -1)
 
1203
        return true;   //error
 
1204
 
 
1205
    *step = to_step(pitch[i--]);
 
1206
    if (*step == -1)
 
1207
        return true;   //error
 
1208
 
 
1209
    if (++i == 0)
 
1210
    {
 
1211
        *accidentals = ImoNote::k_no_accidentals;
 
1212
        return false;   //no error
 
1213
    }
 
1214
    else
 
1215
        *accidentals = to_accidentals(pitch.substr(0, i));
 
1216
    if (*accidentals == -1)
 
1217
        return true;   //error
 
1218
 
 
1219
    return false;  //no error
 
1220
}
 
1221
 
 
1222
NoteTypeAndDots ldp_duration_to_components(const string& duration)
 
1223
{
 
1224
    // Return struct with noteType and dots.
 
1225
    // If error, noteType is set to unknown and dots to zero
 
1226
 
 
1227
    size_t size = duration.length();
 
1228
    if (size == 0)
 
1229
        return NoteTypeAndDots(ImoNoteRest::k_unknown, 0);   //error
 
1230
 
 
1231
    //duration
 
1232
    int noteType = to_note_type(duration[0]);
 
1233
    if (noteType == -1)
 
1234
        return NoteTypeAndDots(ImoNoteRest::k_unknown, 0);   //error
 
1235
 
 
1236
    //dots
 
1237
    int dots = 0;
 
1238
    for (size_t i=1; i < size; i++)
 
1239
    {
 
1240
        if (duration[i] == '.')
 
1241
            dots++;
 
1242
        else
 
1243
            return NoteTypeAndDots(ImoNoteRest::k_unknown, 0);   //error
 
1244
    }
 
1245
 
 
1246
    return NoteTypeAndDots(noteType, dots);   //no error
 
1247
}
 
1248
 
 
1249
float to_duration(int nNoteType, int nDots)
 
1250
{
 
1251
    //compute duration without modifiers
 
1252
    float rDuration = pow(2.0f, (10 - nNoteType));
 
1253
 
 
1254
    //take dots into account
 
1255
    switch (nDots)
 
1256
    {
 
1257
        case 0:                             break;
 
1258
        case 1: rDuration *= 1.5f;          break;
 
1259
        case 2: rDuration *= 1.75f;         break;
 
1260
        case 3: rDuration *= 1.875f;        break;
 
1261
        case 4: rDuration *= 1.9375f;       break;
 
1262
        case 5: rDuration *= 1.96875f;      break;
 
1263
        case 6: rDuration *= 1.984375f;     break;
 
1264
        case 7: rDuration *= 1.9921875f;    break;
 
1265
        case 8: rDuration *= 1.99609375f;   break;
 
1266
        case 9: rDuration *= 1.998046875f;  break;
 
1267
        default:
 
1268
            ;
 
1269
            //wxLogMessage(_T("[to_duration] Program limit: do you really need more than nine dots?"));
 
1270
    }
 
1271
 
 
1272
    return rDuration;
 
1273
}
 
1274
 
 
1275
 
 
1276
}  //namespace lomse