~s-cecilio/lenmus/v5.3

« back to all changes in this revision

Viewing changes to src/graphic/GraphicManager.cpp

  • Committer: cecilios
  • Date: 2012-09-11 16:59:18 UTC
  • Revision ID: svn-v4:2587a929-2f0e-0410-ae78-fe6f687d5efe:branches/TRY-5.0:730
Paths: fixed problem with installation folders. Fixed Chinese ISO language code

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//--------------------------------------------------------------------------------------
2
 
//    LenMus Phonascus: The teacher of music
3
 
//    Copyright (c) 2002-2007 Cecilio Salmeron
4
 
//
5
 
//    This program 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 2 of the License, or (at your option) any later version.
8
 
//
9
 
//    This program 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 with this 
14
 
//    program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, 
15
 
//    Fifth Floor, Boston, MA  02110-1301, USA.
16
 
//
17
 
//    For any comment, suggestion or feature request, please contact the manager of 
18
 
//    the project at cecilios@users.sourceforge.net
19
 
//
20
 
//-------------------------------------------------------------------------------------
21
 
 
22
 
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
23
 
#pragma implementation "GraphicManager.h"
24
 
#endif
25
 
 
26
 
// For compilers that support precompilation, includes "wx.h".
27
 
#include "wx/wxprec.h"
28
 
 
29
 
#ifdef __BORLANDC__
30
 
#pragma hdrstop
31
 
#endif
32
 
 
33
 
#include "wx/image.h"
34
 
 
35
 
#include "GraphicManager.h"
36
 
#include "Formatter4.h"
37
 
#include "AggDrawer.h"
38
 
#include "../score/ObjOptions.h"
39
 
 
40
 
//access to colors
41
 
#include "../globals/Colors.h"
42
 
extern lmColors* g_pColors;
43
 
 
44
 
// Definition of the BitmapList class
45
 
#include <wx/listimpl.cpp>
46
 
WX_DEFINE_LIST(BitmapList);
47
 
 
48
 
// access to global some global flags
49
 
extern bool g_fUseAntiAliasing;         // in TheApp.cpp 
50
 
 
51
 
//-----------------------------------------------------------------------------------------
52
 
 
53
 
lmGraphicManager::lmGraphicManager()
54
 
{
55
 
    Create((lmScore*)NULL, (lmPaper*)NULL);
56
 
}
57
 
 
58
 
lmGraphicManager::lmGraphicManager(lmScore* pScore, lmPaper* pPaper)
59
 
{
60
 
    Create(pScore, pPaper);
61
 
}
62
 
 
63
 
void lmGraphicManager::Create(lmScore* pScore, lmPaper* pPaper)
64
 
{
65
 
    m_pScore = pScore;
66
 
    m_pPaper = pPaper;
67
 
 
68
 
    //initializations
69
 
    m_pBoxScore = (lmBoxScore*) NULL;
70
 
    m_rScale = 0;
71
 
    m_fReLayout = true;
72
 
    m_nLastScoreID = -1;
73
 
    m_xPageSize = 0;
74
 
    m_yPageSize = 0;
75
 
 
76
 
    m_nHighlightedPage = 0;
77
 
    m_pAuxBitmap = (wxBitmap*)NULL;
78
 
    m_fHighlight = false;
79
 
 
80
 
}
81
 
 
82
 
 
83
 
 
84
 
lmGraphicManager::~lmGraphicManager()
85
 
{
86
 
    if (m_pBoxScore) {
87
 
        delete m_pBoxScore;
88
 
        m_pBoxScore = (lmBoxScore*) NULL;
89
 
    }
90
 
 
91
 
    DeleteBitmaps();
92
 
 
93
 
    if (m_pAuxBitmap) {
94
 
        delete m_pAuxBitmap;
95
 
        m_pAuxBitmap = (wxBitmap*)NULL;
96
 
    }
97
 
 
98
 
}
99
 
 
100
 
int lmGraphicManager::GetNumPages()
101
 
{
102
 
    if (m_pBoxScore)
103
 
        return m_pBoxScore->GetNumPages();
104
 
    else
105
 
        return 0;
106
 
}
107
 
 
108
 
void lmGraphicManager::Layout()
109
 
{
110
 
    // The goal of this method is to parse the IIR representation of a score and
111
 
    // generate the graphical representation so that it can be displayed or printed. 
112
 
    // The result is a lmBoxScore object.
113
 
 
114
 
    if (m_pBoxScore) {
115
 
        delete m_pBoxScore;
116
 
        m_pBoxScore = (lmBoxScore*) NULL;
117
 
    }
118
 
    lmFormatter4 oFormatter;   //the formatter object
119
 
    m_pBoxScore = oFormatter.Layout(m_pScore, m_pPaper);
120
 
    wxASSERT(m_pBoxScore);
121
 
    m_fReLayout = false;
122
 
 
123
 
}
124
 
 
125
 
void lmGraphicManager::Render()
126
 
{
127
 
    if (!m_pBoxScore) return;
128
 
    m_pBoxScore->Render(m_pPaper);
129
 
 
130
 
}
131
 
 
132
 
wxBitmap* lmGraphicManager::Render(bool fUseBitmaps, int nPage)
133
 
{
134
 
    //Renders page 1..n.
135
 
 
136
 
    if (!fUseBitmaps) {
137
 
        //Render page directly on the DC
138
 
        if (m_pBoxScore) m_pBoxScore->RenderPage(nPage, m_pPaper);
139
 
        return (wxBitmap*)NULL;
140
 
    }
141
 
    else {
142
 
        //Return the offscreen bitmap for the requested page
143
 
        wxBitmap* pBitmap = GetPageBitmap(nPage);
144
 
        if (!pBitmap) {
145
 
            if (!g_fUseAntiAliasing) {
146
 
                // standard DC renderization. Aliased.
147
 
                pBitmap = NewBitmap(nPage);
148
 
                wxMemoryDC memDC;   // Allocate a DC in memory for the offscreen bitmap
149
 
                memDC.SelectObject(*pBitmap);
150
 
                m_pPaper->SetDrawer(new lmDirectDrawer(&memDC));
151
 
                memDC.Clear();
152
 
                memDC.SetMapMode(lmDC_MODE);
153
 
                memDC.SetUserScale( m_rScale, m_rScale );
154
 
                m_pBoxScore->RenderPage(nPage, m_pPaper);
155
 
                memDC.SelectObject(wxNullBitmap);
156
 
            }
157
 
            else {
158
 
                // anti-aliased renderization
159
 
                wxMemoryDC memDC;
160
 
                pBitmap = new wxBitmap(1, 1);     //allocate something to paint on it
161
 
                memDC.SelectObject(*pBitmap);
162
 
                memDC.SetMapMode(lmDC_MODE);
163
 
                memDC.SetUserScale( m_rScale, m_rScale );
164
 
                lmAggDrawer* pDrawer = new lmAggDrawer(&memDC, m_xPageSize, m_yPageSize);
165
 
                m_pPaper->SetDrawer(pDrawer);
166
 
                wxASSERT(m_pBoxScore);  //Layout phase omitted?
167
 
                m_pBoxScore->RenderPage(nPage, m_pPaper);
168
 
 
169
 
                memDC.SelectObject(wxNullBitmap);
170
 
                delete pBitmap;
171
 
 
172
 
                //Make room for the new bitmap
173
 
                //! @todo
174
 
 
175
 
                //Add bitmap to the offscreen collection
176
 
                pBitmap = new wxBitmap(pDrawer->GetImageBuffer());
177
 
                AddBitmap(nPage, pBitmap);
178
 
            }
179
 
        }
180
 
        return pBitmap;
181
 
    }
182
 
}
183
 
 
184
 
void lmGraphicManager::PrepareForHighlight()
185
 
{
186
 
    // The score is going to be highlighted while played back. This method
187
 
    // saves de AGGDrawer bitmap buffers, to achive fast un-highlight by just
188
 
    // restoring the original bitmap.
189
 
    //wxLogMessage(_T("[lmGraphicManager::PrepareForHighlight]"));
190
 
 
191
 
    //If this method is invoked, a score must be currently displayed. This implies
192
 
    //that Layout() has benn invoked and, therefore, a BoxScore object exists. 
193
 
    wxASSERT(m_pBoxScore);  //Layout phase omitted?
194
 
 
195
 
    //If anti-aliased is not used there is nothing to do in this method
196
 
    if (!g_fUseAntiAliasing) return;
197
 
 
198
 
    //If anti-aliased is used, bitmaps must exist, at least for currently displayed page.
199
 
    wxASSERT(m_cBitmaps.GetCount() > 0);
200
 
 
201
 
    //As we do not know which bitmap to save ("Play" normally starts at page 1 but
202
 
    //not always: i.e. when starting at a certain measure number) this method
203
 
    //just deletes all auxiliary bitmap data.
204
 
    m_nHighlightedPage = 0;
205
 
    if (m_pAuxBitmap) {
206
 
        delete m_pAuxBitmap;
207
 
        m_pAuxBitmap = (wxBitmap*)NULL;
208
 
    }
209
 
 
210
 
    //Finally, signal that all upcoming drawing is for highlight
211
 
    m_fHighlight = true;
212
 
 
213
 
}
214
 
 
215
 
void lmGraphicManager::Prepare(lmScore* pScore, lmLUnits paperWidth, lmLUnits paperHeight,
216
 
                               double rScale, lmPaper* pPaper, int nOptions)
217
 
{
218
 
    //This method informs GraphicManager about the common parameters (the score,
219
 
    //the paper, the scale, etc..) for a series of to subsequent Render()
220
 
    //invocations.
221
 
    //The GraphicManager must verify if all stored values are stil valid and, if not,
222
 
    //do whatever is necessary, i.e. delete invalid offscreen bitmaps.
223
 
    //Also, it must prepare anything that could be necessary, i.e. force a re-layout
224
 
    //of the score.
225
 
 
226
 
 
227
 
 
228
 
    //Is it necessary to force a re-layout? 
229
 
    // Yes in following cases:
230
 
    // - the first time a score is going to be rendered
231
 
    // - if paper size has changed and so requested (option lmRELAYOUT_ON_PAPER_SIZE_CHANGE)
232
 
    // - if explicitly requested (option lmFORCE_RELAYOUT)
233
 
    bool fLayoutScore = !m_pScore || m_fReLayout
234
 
                || m_nLastScoreID != pScore->GetID()
235
 
                || (nOptions & lmFORCE_RELAYOUT)
236
 
                || ( (nOptions & lmRELAYOUT_ON_PAPER_SIZE_CHANGE)  && 
237
 
                     (m_xPageSize != paperWidth || m_yPageSize != paperHeight) );
238
 
 
239
 
    //Is it necessary to delete stored offscreen bitmaps?
240
 
    //Yes in following cases:
241
 
    // - When the scale (zooming factor) has changed
242
 
    // - When a re-layout takes place
243
 
    bool fDeleteBitmaps = (m_rScale != rScale) || fLayoutScore;
244
 
 
245
 
    //store received values
246
 
    m_pPaper = pPaper;
247
 
    m_rScale = rScale;
248
 
    m_xPageSize = paperWidth;
249
 
    m_yPageSize = paperHeight;
250
 
    m_pScore = pScore;
251
 
    m_nLastScoreID = m_pScore->GetID();
252
 
 
253
 
    //re-layout the score if necesary
254
 
    if (fLayoutScore) Layout();
255
 
 
256
 
    //delete existing offscreen bitmaps if necessary
257
 
    if (fDeleteBitmaps) DeleteBitmaps();
258
 
 
259
 
    //wxLogMessage(_T("[lmGraphicManager::Prepare] fLayoutScore=%s, fDeleteBitmaps=%s, Hay BoxScore=%s"), 
260
 
    //    (fLayoutScore ? _T("Yes") : _T("No")), 
261
 
    //    (fDeleteBitmaps ? _T("Yes") : _T("No")), 
262
 
    //    (m_pBoxScore ? _T("Yes") : _T("No")) );
263
 
 
264
 
}
265
 
 
266
 
void lmGraphicManager::DeleteBitmaps()
267
 
{
268
 
    wxBitmapListNode* pNode = m_cBitmaps.GetFirst();
269
 
    while (pNode) {
270
 
        wxBitmap* pBitmap = pNode->GetData();
271
 
        delete pBitmap;
272
 
        delete pNode;
273
 
        pNode = m_cBitmaps.GetFirst();
274
 
    }
275
 
    m_aBitmapPage.Clear();
276
 
 
277
 
}
278
 
 
279
 
wxBitmap* lmGraphicManager::GetPageBitmap(int nPage)
280
 
{
281
 
    // nPage = 1 .. n
282
 
    // Get the bitmap for requested page, or NULL if no bitmap exits for that page.
283
 
 
284
 
    wxASSERT(nPage > 0);
285
 
        
286
 
    int i;
287
 
    for (i=0; i < (int)m_cBitmaps.GetCount(); i++) {
288
 
        if (m_aBitmapPage.Item(i) == nPage) {
289
 
            wxBitmapListNode* pNode = m_cBitmaps.Item(i);
290
 
            return (wxBitmap*)pNode->GetData();
291
 
        }
292
 
    }
293
 
    return (wxBitmap*)NULL;
294
 
 
295
 
}
296
 
 
297
 
wxBitmap* lmGraphicManager::NewBitmap(int nPage)
298
 
{
299
 
    // nPage = 1 .. n
300
 
    // Makes room for a new bitmap, for page nPage
301
 
    // and returns it (empty bitmap)
302
 
 
303
 
    //wxLogMessage(_T("[lmGraphicManager::NewBitmap] Page = %d"), nPage);
304
 
 
305
 
    //Make room for the new bitmap
306
 
    //! @todo
307
 
 
308
 
    //Allocate the new bit map
309
 
    wxBitmap* pBitmap = new wxBitmap(m_xPageSize, m_yPageSize);
310
 
    //wxLogMessage(_T("[lmGraphicManager::NewBitmap] Allocated bitmap (%d, %d) pixels, %d bits/pixel. Size= %.02f MB"),
311
 
    //    m_xPageSize, m_yPageSize, pBitmap->GetDepth(), (double)((m_xPageSize * m_yPageSize * pBitmap->GetDepth())/8000000.) );
312
 
    if (!pBitmap || !pBitmap->Ok()) {
313
 
        if (pBitmap) {
314
 
            delete pBitmap;
315
 
            pBitmap = (wxBitmap *) NULL;
316
 
        }
317
 
        wxLogMessage(_T("[lmGraphicManager::NewBitmap] Bitmap size (%d, %d) pixels."), m_xPageSize, m_yPageSize);
318
 
        wxMessageBox(_("Sorry, not enough memory to create a Bitmap to display the page."),
319
 
            _T("lmGraphicManager::NewBitmap"), wxOK);
320
 
        ::wxExit();
321
 
    }
322
 
 
323
 
    // add the new bitmap to the list and store its size
324
 
    AddBitmap(nPage, pBitmap);
325
 
 
326
 
    return pBitmap;
327
 
}
328
 
 
329
 
void lmGraphicManager::AddBitmap(int nPage, wxBitmap* pBitmap)
330
 
{
331
 
    // nPage = 1 .. n
332
 
    // Adds the received bitmap to the list, associating it to page nPage
333
 
 
334
 
    //wxLogMessage(_T("[lmGraphicManager::AddBitmap] Page = %d"), nPage);
335
 
 
336
 
    // add the new bitmap to the list and store its size
337
 
    m_cBitmaps.Append(pBitmap);
338
 
    m_aBitmapPage.Add(nPage);
339
 
 
340
 
    m_xBitmapSize = m_xPageSize;
341
 
    m_yBitmapSize = m_yPageSize;
342
 
 
343
 
}
344
 
 
345
 
void lmGraphicManager::BitmapsToFile(wxString& sFilename, wxString& sExt, int nImgType)
346
 
{
347
 
    wxASSERT(nImgType == wxBITMAP_TYPE_BMP || nImgType == wxBITMAP_TYPE_JPEG
348
 
             || nImgType == wxBITMAP_TYPE_PNG || nImgType == wxBITMAP_TYPE_PCX
349
 
             || nImgType == wxBITMAP_TYPE_PNM);
350
 
 
351
 
    wxBitmapListNode* pNode = m_cBitmaps.GetFirst();
352
 
    int i = 1;
353
 
    while (pNode) {
354
 
        wxBitmap* pBitmap = pNode->GetData();
355
 
        wxImage oImg = pBitmap->ConvertToImage();
356
 
        wxString sName = wxString::Format(_T("%s_%d.%s"), sFilename, m_aBitmapPage.Item(i-1), sExt);
357
 
        oImg.SaveFile(sName, nImgType);
358
 
        pNode = pNode->GetNext();
359
 
        i++;
360
 
    }
361
 
 
362
 
}
363
 
 
364
 
void lmGraphicManager::ExportAsImage(wxString& sFilename, wxString& sExt, int nImgType)
365
 
{
366
 
    //Before invoking this method, Prepare() must be invoked
367
 
 
368
 
    wxASSERT(nImgType == wxBITMAP_TYPE_BMP || nImgType == wxBITMAP_TYPE_JPEG
369
 
             || nImgType == wxBITMAP_TYPE_PNG || nImgType == wxBITMAP_TYPE_PCX
370
 
             || nImgType == wxBITMAP_TYPE_PNM);
371
 
 
372
 
 
373
 
    int i;
374
 
    for(i=1; i <= GetNumPages(); i++) {
375
 
        wxBitmap* pBitmap = Render(lmUSE_BITMAPS, i);
376
 
        wxImage oImg = pBitmap->ConvertToImage();
377
 
        wxString sName = wxString::Format(_T("%s_%d.%s"), sFilename, m_aBitmapPage.Item(i-1), sExt);
378
 
        oImg.SaveFile(sName, nImgType);
379
 
    }
380
 
 
381
 
}
382