diff options
Diffstat (limited to 'muse2')
120 files changed, 22524 insertions, 1466 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 8143bb0c..efa6b86d 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -114,6 +114,20 @@ pthread_t splashThread; // // pyscript->runPythonScript(script); // } + +void MusE::clearScoreMenuMappers() +{ + delete scoreOneStaffPerTrackMapper; + delete scoreAllInOneMapper; + + scoreOneStaffPerTrackMapper = new QSignalMapper(this); + scoreAllInOneMapper = new QSignalMapper(this); + + connect(scoreOneStaffPerTrackMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_oneStaffPerTrack(QWidget*))); + connect(scoreAllInOneMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_allInOne(QWidget*))); +} + + //--------------------------------------------------------- // sleep function //--------------------------------------------------------- @@ -803,6 +817,8 @@ MusE::MusE(int argc, char** argv) : QMainWindow() editSignalMapper = new QSignalMapper(this); midiPluginSignalMapper = new QSignalMapper(this); followSignalMapper = new QSignalMapper(this); + scoreOneStaffPerTrackMapper = new QSignalMapper(this); + scoreAllInOneMapper = new QSignalMapper(this); song = new Song("song"); song->blockSignals(true); @@ -977,7 +993,15 @@ MusE::MusE(int argc, char** argv) : QMainWindow() editOutsideLoopAction = new QAction(QIcon(*select_outside_loopIcon), tr("&Outside Loop"), this); editAllPartsAction = new QAction( QIcon(*select_all_parts_on_trackIcon), tr("All &Parts on Track"), this); - startScoreEditAction = new QAction(*scoreIconSet, tr("Score"), this); + + scoreSubmenu = new QMenu(tr("Score"), this); + scoreSubmenu->setIcon(QIcon(*scoreIconSet)); + + scoreAllInOneSubsubmenu = new QMenu(tr("all parts in one staff"), this); + scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per part"), this); + + updateScoreMenus(); + startPianoEditAction = new QAction(*pianoIconSet, tr("Pianoroll"), this); startDrumEditAction = new QAction(QIcon(*edit_drummsIcon), tr("Drums"), this); startListEditAction = new QAction(QIcon(*edit_listIcon), tr("List"), this); @@ -1127,10 +1151,12 @@ MusE::MusE(int argc, char** argv) : QMainWindow() connect(editSignalMapper, SIGNAL(mapped(int)), this, SLOT(cmd(int))); connect(startPianoEditAction, SIGNAL(activated()), SLOT(startPianoroll())); - connect(startScoreEditAction, SIGNAL(activated()), SLOT(startScoreEdit())); connect(startDrumEditAction, SIGNAL(activated()), SLOT(startDrumEditor())); connect(startListEditAction, SIGNAL(activated()), SLOT(startListEditor())); connect(startWaveEditAction, SIGNAL(activated()), SLOT(startWaveEditor())); + connect(scoreOneStaffPerTrackMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_oneStaffPerTrack(QWidget*))); + connect(scoreAllInOneMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_allInOne(QWidget*))); + connect(masterGraphicAction, SIGNAL(activated()), SLOT(startMasterEditor())); connect(masterListAction, SIGNAL(activated()), SLOT(startLMasterEditor())); @@ -1346,7 +1372,9 @@ MusE::MusE(int argc, char** argv) : QMainWindow() menuEdit->addSeparator(); menuEdit->addAction(startPianoEditAction); - menuEdit->addAction(startScoreEditAction); + menuEdit->addMenu(scoreSubmenu); + scoreSubmenu->addMenu(scoreAllInOneSubsubmenu); + scoreSubmenu->addMenu(scoreOneStaffPerTrackSubsubmenu); menuEdit->addAction(startDrumEditAction); menuEdit->addAction(startListEditAction); menuEdit->addAction(startWaveEditAction); @@ -3424,29 +3452,89 @@ PartList* MusE::getMidiPartsToEdit() return pl; } +void MusE::scoreNamingChanged() +{ + updateScoreMenus(); +} + +void MusE::updateScoreMenus() +{ + QAction* action; + + + scoreOneStaffPerTrackSubsubmenu->clear(); + scoreAllInOneSubsubmenu->clear(); + + + action=new QAction(tr("New"), this); + connect(action, SIGNAL(activated()), scoreOneStaffPerTrackMapper, SLOT(map())); + scoreOneStaffPerTrackMapper->setMapping(action, (QWidget*)NULL); + scoreOneStaffPerTrackSubsubmenu->addAction(action); + + + action=new QAction(tr("New"), this); //the above action may NOT be reused! + connect(action, SIGNAL(activated()), scoreAllInOneMapper, SLOT(map())); + scoreAllInOneMapper->setMapping(action, (QWidget*)NULL); + scoreAllInOneSubsubmenu->addAction(action); + + for (ToplevelList::iterator it=toplevels.begin(); it!=toplevels.end(); it++) + if (it->type()==Toplevel::SCORE) + { + ScoreEdit* score = (ScoreEdit*) it->cobject(); + + action=new QAction(score->get_name(), this); + connect(action, SIGNAL(activated()), scoreOneStaffPerTrackMapper, SLOT(map())); + scoreOneStaffPerTrackMapper->setMapping(action, (QWidget*)score); + scoreOneStaffPerTrackSubsubmenu->addAction(action); + + + action=new QAction(score->get_name(), this); //the above action may NOT be reused! + connect(action, SIGNAL(activated()), scoreAllInOneMapper, SLOT(map())); + scoreAllInOneMapper->setMapping(action, (QWidget*)score); + scoreAllInOneSubsubmenu->addAction(action); + } +} + //--------------------------------------------------------- // startScoreEdit //--------------------------------------------------------- -void MusE::startScoreEdit() - { - PartList* pl = getMidiPartsToEdit(); - if (pl == 0) - return; - startScoreEdit(pl, true); - } +void MusE::openInScoreEdit_oneStaffPerTrack(QWidget* dest) +{ + openInScoreEdit((ScoreEdit*)dest, false); +} -void MusE::startScoreEdit(PartList* pl, bool showDefaultCtrls) - { +void MusE::openInScoreEdit_allInOne(QWidget* dest) +{ + openInScoreEdit((ScoreEdit*)dest, true); +} - ScoreEdit* scoreedit = new ScoreEdit(pl, this, 0, arranger->cursorValue()); - if(showDefaultCtrls) // p4.0.12 - scoreedit->addCtrl(); - scoreedit->show(); - toplevels.push_back(Toplevel(Toplevel::PIANO_ROLL, (unsigned long)(scoreedit), scoreedit)); - connect(scoreedit, SIGNAL(deleted(unsigned long)), SLOT(toplevelDeleted(unsigned long))); - connect(muse, SIGNAL(configChanged()), scoreedit, SLOT(configChanged())); - } +void MusE::openInScoreEdit(ScoreEdit* destination, bool allInOne) +{ + PartList* pl = getMidiPartsToEdit(); + if (pl == 0) + return; + openInScoreEdit(destination, pl, allInOne); +} + +void MusE::openInScoreEdit(ScoreEdit* destination, PartList* pl, bool allInOne) +{ + if (destination==NULL) // if no destination given, create a new one + { + destination = new ScoreEdit(pl, this, 0, arranger->cursorValue()); + destination->show(); + toplevels.push_back(Toplevel(Toplevel::SCORE, (unsigned long)(destination), destination)); + connect(destination, SIGNAL(deleted(unsigned long)), SLOT(toplevelDeleted(unsigned long))); + connect(destination, SIGNAL(name_changed()), SLOT(scoreNamingChanged())); + //connect(muse, SIGNAL(configChanged()), destination, SLOT(config_changed())); + //commented out by flo, because the ScoreEditor connects to all + //relevant signals on his own + + updateScoreMenus(); + } + + destination->add_parts(pl, allInOne); +} //--------------------------------------------------------- // startPianoroll @@ -3667,6 +3755,7 @@ void MusE::toplevelDeleted(unsigned long tl) { for (iToplevel i = toplevels.begin(); i != toplevels.end(); ++i) { if (i->object() == tl) { + bool mustUpdateScoreMenus=false; switch(i->type()) { case Toplevel::MARKER: break; @@ -3685,8 +3774,12 @@ void MusE::toplevelDeleted(unsigned long tl) case Toplevel::WAVE: case Toplevel::LMASTER: break; + case Toplevel::SCORE: + mustUpdateScoreMenus=true; } toplevels.erase(i); + if (mustUpdateScoreMenus) + updateScoreMenus(); return; } } @@ -4839,6 +4932,7 @@ again: case Toplevel::MARKER: break; case Toplevel::PIANO_ROLL: + case Toplevel::SCORE: case Toplevel::LISTE: case Toplevel::DRUM: case Toplevel::MASTER: diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 168602d3..8a9fdac0 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -65,6 +65,7 @@ class Appearance; class WaveTrack; class AudioOutput; class EditInstrument; +class ScoreEdit; #define MENU_ADD_SYNTH_ID_BASE 0x1000 @@ -109,7 +110,7 @@ class MusE : public QMainWindow QAction *editInvertSelectionAction, *editInsideLoopAction, *editOutsideLoopAction, *editAllPartsAction; QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction; QAction *trackAInputAction, *trackAAuxAction; - QAction *startPianoEditAction, *startDrumEditAction, *startListEditAction, *startWaveEditAction, *startScoreEditAction; + QAction *startPianoEditAction, *startDrumEditAction, *startListEditAction, *startWaveEditAction; QAction *masterGraphicAction, *masterListAction; QAction *midiTransposeAction; QAction *midiTransformerAction; @@ -158,6 +159,7 @@ class MusE : public QMainWindow QMenu* menu_audio, *menuAutomation; QMenu* menu_functions, *menuScriptPlugins; QMenu* select, *master, *midiEdit, *addTrack; + QMenu *scoreSubmenu, *scoreOneStaffPerTrackSubsubmenu, *scoreAllInOneSubsubmenu; // Special 'stay-open' menu for routes. PopupMenu* routingPopupMenu; @@ -220,6 +222,8 @@ class MusE : public QMainWindow QSignalMapper *editSignalMapper; QSignalMapper *midiPluginSignalMapper; QSignalMapper *followSignalMapper; + QSignalMapper *scoreOneStaffPerTrackMapper; + QSignalMapper *scoreAllInOneMapper; signals: void configChanged(); @@ -261,8 +265,15 @@ class MusE : public QMainWindow void startDrumEditor(); void startDrumEditor(PartList* /*pl*/, bool /*showDefaultCtrls*/ = false); void startEditor(Track*); - void startScoreEdit(); - void startScoreEdit(PartList* /*pl*/, bool /*showDefaultCtrls*/ = false); + + void openInScoreEdit(ScoreEdit* destination, PartList* pl, bool allInOne=false); + void openInScoreEdit(ScoreEdit* destination, bool allInOne=false); + void openInScoreEdit_allInOne(QWidget* destination); + void openInScoreEdit_oneStaffPerTrack(QWidget* destination); + void clearScoreMenuMappers(); + void updateScoreMenus(); + void scoreNamingChanged(); + void startPianoroll(); void startPianoroll(PartList* /*pl*/, bool /*showDefaultCtrls*/ = false); void startWaveEditor(); @@ -320,7 +331,7 @@ class MusE : public QMainWindow void execDeliveredScript(int); void execUserScript(int); - + public slots: bool saveAs(); void bounceToFile(AudioOutput* ao = 0); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index e2c2b32d..6068c743 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -994,7 +994,8 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) // If no items selected, use the one clicked on. if(!selfound) item->part()->setColorIndex(curColorIndex); - + + song->update(SC_PART_MODIFIED); redraw(); break; } diff --git a/muse2/muse/cobject.h b/muse2/muse/cobject.h index 8e21eaf0..9a80b2b1 100644 --- a/muse2/muse/cobject.h +++ b/muse2/muse/cobject.h @@ -38,7 +38,7 @@ class TopWin : public QMainWindow class Toplevel { public: enum ToplevelType { PIANO_ROLL, LISTE, DRUM, MASTER, WAVE, - LMASTER, CLIPLIST, MARKER + LMASTER, CLIPLIST, MARKER, SCORE #ifdef PATCHBAY , M_PATCHBAY #endif /* PATCHBAY */ diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index f236a0d5..e904ce46 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -1,13 +1,15 @@ //========================================================= // MusE // Linux Music Editor -// $Id: ScoreEdit.cpp,v 1.25.2.15 2009/11/16 11:29:33 lunar_shuttle Exp $ -// (C) Copyright 1999 Werner Schweer (ws@seh.de) +// scoreedit.cpp +// (C) Copyright 2011 Florian Jung (florian.a.jung@web.de) //========================================================= + #include <QLayout> #include <QSizeGrip> #include <QLabel> +#include <QScrollBar> #include <QPushButton> #include <QToolButton> #include <QToolTip> @@ -18,6 +20,7 @@ #include <QClipboard> #include <QDir> #include <QAction> +#include <QActionGroup> #include <QKeySequence> #include <QKeyEvent> #include <QGridLayout> @@ -26,9 +29,18 @@ #include <QMimeData> #include <QScrollArea> #include <QSettings> +#include <QImage> +#include <QInputDialog> +#include <QMessageBox> #include <stdio.h> +#include <math.h> + +#include <iostream> +#include <sstream> +using namespace std; +#include "app.h" #include "xml.h" #include "mtscale.h" #include "prcanvas.h" @@ -51,1361 +63,3314 @@ #include "mtrackinfo.h" -int ScoreEdit::_quantInit = 96; -int ScoreEdit::_rasterInit = 96; -int ScoreEdit::_widthInit = 600; -int ScoreEdit::_heightInit = 400; -int ScoreEdit::_quantStrengthInit = 80; // 1 - 100% -int ScoreEdit::_quantLimitInit = 50; // tick value -bool ScoreEdit::_quantLenInit = false; -int ScoreEdit::_toInit = 0; -int ScoreEdit::colorModeInit = 0; +#include "sig.h" + + +string IntToStr(int i); +QString IntToQStr(int i); + + +#define SPLIT_NOTE 60 +//TODO: let the user specify that somehow? + + + + + +//PIXELS_PER_NOTEPOS must be greater or equal to 3*NOTE_XLEN + 2*NOTE_SHIFT +//because if tick 0 is at x=0: the notes can be shifted by NOTE_SHIFT. +//additionally, they can be moved by NOTE_XLEN (collision avoiding) +//then, they have their own width, which is NOTE_XLEN/2 into the x>0-area +//the same thing applies to the x<0-area + +// OOO +// | +// ^actual calculated x, without shifting or moving +// ^ and +// ^ : moved note (by XLEN) +// additionally, a shift is possible +// total_width = shift + move + note_xlen + move + shift, where move==note_xlen +// total_width = 2*shift + 3*note_xlen +// if total_width is greater than px_per_notepos, there will be collisions! + + + + + +//do NOT put parentheses around this! +#define PAGESTEP 3/4 + + +#define SCROLL_MARGIN 10 +#define SCROLL_SPEED 5 +//SCROLL_SPEED is in (scroll_pixels per second) per mouse-move-pixel +#define SCROLL_SPEED_MAX 500 +//SCROLL_SPEED_MAX is in scroll_pixels_per_second + + + +#define STAFF_DISTANCE (10*YLEN) +#define GRANDSTAFF_DISTANCE (8*YLEN) + +QString create_random_string(int len=8) +{ + string result; + + for (int i=0;i<len;i++) + result+=char((rand() % 26) + 'A'); + + return QString(result.c_str()); +} + + + + + -static const int xscale = -10; -static const int yscale = 1; -static const int pianoWidth = 40; -static int ScoreEditTools = PointerTool | PencilTool | RubberTool | DrawTool; +QPixmap *pix_whole, *pix_half, *pix_quarter; // arrays [NUM_PARTCOLORS+2] +QPixmap *pix_dot, *pix_b, *pix_sharp, *pix_noacc; // arrays [NUM_PARTCOLORS+2] +QPixmap *pix_r1, *pix_r2, *pix_r4, *pix_r8, *pix_r16; // pointers +QPixmap *pix_flag_up, *pix_flag_down; // arrays [4] +QPixmap *pix_num; // array [10] +QPixmap *pix_clef_violin, *pix_clef_bass; //pointers +bool pixmaps_loaded=false; + + + + +int ScoreEdit::serial=1; +set<QString> ScoreEdit::names; + //--------------------------------------------------------- // ScoreEdit //--------------------------------------------------------- ScoreEdit::ScoreEdit(PartList* pl, QWidget* parent, const char* name, unsigned initPos) - : MidiEditor(_quantInit, _rasterInit, pl, parent, name) - { - deltaMode = false; - resize(_widthInit, _heightInit); - selPart = 0; - quantConfig = 0; - _playEvents = false; - _quantStrength = _quantStrengthInit; - _quantLimit = _quantLimitInit; - _quantLen = _quantLenInit; - _to = _toInit; - colorMode = colorModeInit; - - QSignalMapper* mapper = new QSignalMapper(this); - QSignalMapper* colorMapper = new QSignalMapper(this); - - //---------Menu---------------------------------- - - menuEdit = menuBar()->addMenu(tr("&Edit")); - - menuEdit->addActions(undoRedo->actions()); - - menuEdit->addSeparator(); - - editCutAction = menuEdit->addAction(QIcon(*editcutIconSet), tr("C&ut")); - mapper->setMapping(editCutAction, PianoCanvas::CMD_CUT); - connect(editCutAction, SIGNAL(triggered()), mapper, SLOT(map())); - - editCopyAction = menuEdit->addAction(QIcon(*editcopyIconSet), tr("&Copy")); - mapper->setMapping(editCopyAction, PianoCanvas::CMD_COPY); - connect(editCopyAction, SIGNAL(triggered()), mapper, SLOT(map())); - - editPasteAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("&Paste")); - mapper->setMapping(editPasteAction, PianoCanvas::CMD_PASTE); - connect(editPasteAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuEdit->addSeparator(); - - editDelEventsAction = menuEdit->addAction(tr("Delete &Events")); - mapper->setMapping(editDelEventsAction, PianoCanvas::CMD_DEL); - connect(editDelEventsAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuEdit->addSeparator(); - - menuSelect = menuEdit->addMenu(QIcon(*selectIcon), tr("&Select")); - - selectAllAction = menuSelect->addAction(QIcon(*select_allIcon), tr("Select &All")); - mapper->setMapping(selectAllAction, PianoCanvas::CMD_SELECT_ALL); - connect(selectAllAction, SIGNAL(triggered()), mapper, SLOT(map())); - - selectNoneAction = menuSelect->addAction(QIcon(*select_deselect_allIcon), tr("&Deselect All")); - mapper->setMapping(selectNoneAction, PianoCanvas::CMD_SELECT_NONE); - connect(selectNoneAction, SIGNAL(triggered()), mapper, SLOT(map())); - - selectInvertAction = menuSelect->addAction(QIcon(*select_invert_selectionIcon), tr("Invert &Selection")); - mapper->setMapping(selectInvertAction, PianoCanvas::CMD_SELECT_INVERT); - connect(selectInvertAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuSelect->addSeparator(); - - selectInsideLoopAction = menuSelect->addAction(QIcon(*select_inside_loopIcon), tr("&Inside Loop")); - mapper->setMapping(selectInsideLoopAction, PianoCanvas::CMD_SELECT_ILOOP); - connect(selectInsideLoopAction, SIGNAL(triggered()), mapper, SLOT(map())); - - selectOutsideLoopAction = menuSelect->addAction(QIcon(*select_outside_loopIcon), tr("&Outside Loop")); - mapper->setMapping(selectOutsideLoopAction, PianoCanvas::CMD_SELECT_OLOOP); - connect(selectOutsideLoopAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuSelect->addSeparator(); - - //selectPrevPartAction = select->addAction(tr("&Previous Part")); - selectPrevPartAction = menuSelect->addAction(QIcon(*select_all_parts_on_trackIcon), tr("&Previous Part")); - mapper->setMapping(selectPrevPartAction, PianoCanvas::CMD_SELECT_PREV_PART); - connect(selectPrevPartAction, SIGNAL(triggered()), mapper, SLOT(map())); - - //selNextPartAction = select->addAction(tr("&Next Part")); - selectNextPartAction = menuSelect->addAction(QIcon(*select_all_parts_on_trackIcon), tr("&Next Part")); - mapper->setMapping(selectNextPartAction, PianoCanvas::CMD_SELECT_NEXT_PART); - connect(selectNextPartAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuConfig = menuBar()->addMenu(tr("&Config")); - - eventColor = menuConfig->addMenu(tr("&Event Color")); - - QActionGroup* actgrp = new QActionGroup(this); - actgrp->setExclusive(true); - - //evColorBlueAction = eventColor->addAction(tr("&Blue")); - evColorBlueAction = actgrp->addAction(tr("&Blue")); - evColorBlueAction->setCheckable(true); - colorMapper->setMapping(evColorBlueAction, 0); - - //evColorPitchAction = eventColor->addAction(tr("&Pitch colors")); - evColorPitchAction = actgrp->addAction(tr("&Pitch colors")); - evColorPitchAction->setCheckable(true); - colorMapper->setMapping(evColorPitchAction, 1); - - //evColorVelAction = eventColor->addAction(tr("&Velocity colors")); - evColorVelAction = actgrp->addAction(tr("&Velocity colors")); - evColorVelAction->setCheckable(true); - colorMapper->setMapping(evColorVelAction, 2); - - connect(evColorBlueAction, SIGNAL(triggered()), colorMapper, SLOT(map())); - connect(evColorPitchAction, SIGNAL(triggered()), colorMapper, SLOT(map())); - connect(evColorVelAction, SIGNAL(triggered()), colorMapper, SLOT(map())); - - eventColor->addActions(actgrp->actions()); - - connect(colorMapper, SIGNAL(mapped(int)), this, SLOT(eventColorModeChanged(int))); - - menuFunctions = menuBar()->addMenu(tr("&Functions")); - - menuFunctions->setTearOffEnabled(true); - - funcOverQuantAction = menuFunctions->addAction(tr("Over Quantize")); - mapper->setMapping(funcOverQuantAction, PianoCanvas::CMD_OVER_QUANTIZE); - connect(funcOverQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcNoteOnQuantAction = menuFunctions->addAction(tr("Note On Quantize")); - mapper->setMapping(funcNoteOnQuantAction, PianoCanvas::CMD_ON_QUANTIZE); - connect(funcNoteOnQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcNoteOnOffQuantAction = menuFunctions->addAction(tr("Note On/Off Quantize")); - mapper->setMapping(funcNoteOnOffQuantAction, PianoCanvas::CMD_ONOFF_QUANTIZE); - connect(funcNoteOnOffQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcIterQuantAction = menuFunctions->addAction(tr("Iterative Quantize")); - mapper->setMapping(funcIterQuantAction, PianoCanvas::CMD_ITERATIVE_QUANTIZE); - connect(funcIterQuantAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuFunctions->addSeparator(); - - funcConfigQuantAction = menuFunctions->addAction(tr("Config Quant...")); - connect(funcConfigQuantAction, SIGNAL(triggered()), this, SLOT(configQuant())); - - menuFunctions->addSeparator(); - - funcGateTimeAction = menuFunctions->addAction(tr("Modify Gate Time")); - mapper->setMapping(funcGateTimeAction, PianoCanvas::CMD_MODIFY_GATE_TIME); - connect(funcGateTimeAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcModVelAction = menuFunctions->addAction(tr("Modify Velocity")); - mapper->setMapping(funcModVelAction, PianoCanvas::CMD_MODIFY_VELOCITY); - connect(funcModVelAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcCrescendoAction = menuFunctions->addAction(tr("Crescendo")); - mapper->setMapping(funcCrescendoAction, PianoCanvas::CMD_CRESCENDO); - funcCrescendoAction->setEnabled(false); - connect(funcCrescendoAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcTransposeAction = menuFunctions->addAction(tr("Transpose")); - mapper->setMapping(funcTransposeAction, PianoCanvas::CMD_TRANSPOSE); - funcTransposeAction->setEnabled(false); - connect(funcTransposeAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcThinOutAction = menuFunctions->addAction(tr("Thin Out")); - mapper->setMapping(funcThinOutAction, PianoCanvas::CMD_THIN_OUT); - funcThinOutAction->setEnabled(false); - connect(funcThinOutAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcEraseEventAction = menuFunctions->addAction(tr("Erase Event")); - mapper->setMapping(funcEraseEventAction, PianoCanvas::CMD_ERASE_EVENT); - funcEraseEventAction->setEnabled(false); - connect(funcEraseEventAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcNoteShiftAction = menuFunctions->addAction(tr("Note Shift")); - mapper->setMapping(funcNoteShiftAction, PianoCanvas::CMD_NOTE_SHIFT); - funcNoteShiftAction->setEnabled(false); - connect(funcNoteShiftAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcMoveClockAction = menuFunctions->addAction(tr("Move Clock")); - mapper->setMapping(funcMoveClockAction, PianoCanvas::CMD_MOVE_CLOCK); - funcMoveClockAction->setEnabled(false); - connect(funcMoveClockAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcCopyMeasureAction = menuFunctions->addAction(tr("Copy Measure")); - mapper->setMapping(funcCopyMeasureAction, PianoCanvas::CMD_COPY_MEASURE); - funcCopyMeasureAction->setEnabled(false); - connect(funcCopyMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcEraseMeasureAction = menuFunctions->addAction(tr("Erase Measure")); - mapper->setMapping(funcEraseMeasureAction, PianoCanvas::CMD_ERASE_MEASURE); - funcEraseMeasureAction->setEnabled(false); - connect(funcEraseMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcDelMeasureAction = menuFunctions->addAction(tr("Delete Measure")); - mapper->setMapping(funcDelMeasureAction, PianoCanvas::CMD_DELETE_MEASURE); - funcDelMeasureAction->setEnabled(false); - connect(funcDelMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcCreateMeasureAction = menuFunctions->addAction(tr("Create Measure")); - mapper->setMapping(funcCreateMeasureAction, PianoCanvas::CMD_CREATE_MEASURE); - funcCreateMeasureAction->setEnabled(false); - connect(funcCreateMeasureAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcSetFixedLenAction = menuFunctions->addAction(tr("Set Fixed Length")); - mapper->setMapping(funcSetFixedLenAction, PianoCanvas::CMD_FIXED_LEN); - connect(funcSetFixedLenAction, SIGNAL(triggered()), mapper, SLOT(map())); - - funcDelOverlapsAction = menuFunctions->addAction(tr("Delete Overlaps")); - mapper->setMapping(funcDelOverlapsAction, PianoCanvas::CMD_DELETE_OVERLAPS); - connect(funcDelOverlapsAction, SIGNAL(triggered()), mapper, SLOT(map())); - - menuPlugins = menuBar()->addMenu(tr("&Plugins")); - song->populateScriptMenu(menuPlugins, this); - - connect(mapper, SIGNAL(mapped(int)), this, SLOT(cmd(int))); - - //---------ToolBar---------------------------------- - tools = addToolBar(tr("ScoreEdit tools")); - tools->setObjectName("ScoreEdit tools"); - tools->addActions(undoRedo->actions()); - tools->addSeparator(); - - srec = new QToolButton(); - srec->setToolTip(tr("Step Record")); - srec->setIcon(*steprecIcon); - srec->setCheckable(true); - tools->addWidget(srec); - - midiin = new QToolButton(); - midiin->setToolTip(tr("Midi Input")); - midiin->setIcon(*midiinIcon); - midiin->setCheckable(true); - tools->addWidget(midiin); - - speaker = new QToolButton(); - speaker->setToolTip(tr("Play Events")); - speaker->setIcon(*speakerIcon); - speaker->setCheckable(true); - tools->addWidget(speaker); - - tools2 = new EditToolBar(this, ScoreEditTools); - addToolBar(tools2); - - QToolBar* panicToolbar = addToolBar(tr("panic")); - panicToolbar->setObjectName("panic"); - panicToolbar->addAction(panicAction); - - //------------------------------------------------------------- - // Transport Bar - QToolBar* transport = addToolBar(tr("transport")); - transport->setObjectName("transport"); - transport->addActions(transportAction->actions()); - - addToolBarBreak(); - toolbar = new Toolbar1(this, _rasterInit, _quantInit); - addToolBar(toolbar); - - addToolBarBreak(); - info = new NoteInfo(this); - addToolBar(info); - - //--------------------------------------------------- - // split - //--------------------------------------------------- - - splitter = new Splitter(Qt::Vertical, mainw, "splitter"); - splitter->setHandleWidth(2); - - hsplitter = new Splitter(Qt::Horizontal, mainw, "hsplitter"); - hsplitter->setChildrenCollapsible(true); - hsplitter->setHandleWidth(2); - - QPushButton* ctrl = new QPushButton(tr("ctrl"), mainw); - //QPushButton* ctrl = new QPushButton(tr("C"), mainw); // Tim. - ctrl->setObjectName("Ctrl"); - ctrl->setFont(config.fonts[3]); - ctrl->setToolTip(tr("Add Controller View")); - hscroll = new ScrollScale(-25, -2, xscale, 20000, Qt::Horizontal, mainw); - ctrl->setFixedSize(pianoWidth, hscroll->sizeHint().height()); - //ctrl->setFixedSize(pianoWidth / 2, hscroll->sizeHint().height()); // Tim. - - // Tim. - /* - QPushButton* trackInfoButton = new QPushButton(tr("T"), mainw); - trackInfoButton->setObjectName("TrackInfo"); - trackInfoButton->setFont(config.fonts[3]); - trackInfoButton->setToolTip(tr("Show track info")); - trackInfoButton->setFixedSize(pianoWidth / 2, hscroll->sizeHint().height()); - */ - - QSizeGrip* corner = new QSizeGrip(mainw); - - midiTrackInfo = new MidiTrackInfo(mainw); - int mtiw = midiTrackInfo->width(); // Save this. - midiTrackInfo->setMinimumWidth(100); - //midiTrackInfo->setMaximumWidth(150); - - midiTrackInfo->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding)); - infoScroll = new QScrollArea; - infoScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - infoScroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - infoScroll->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding)); - infoScroll->setWidget(midiTrackInfo); - infoScroll->setWidgetResizable(true); - //infoScroll->setVisible(false); - //infoScroll->setEnabled(false); - - //hsplitter->addWidget(midiTrackInfo); - hsplitter->addWidget(infoScroll); // Tim. - hsplitter->addWidget(splitter); - - mainGrid->setRowStretch(0, 100); - mainGrid->setColumnStretch(1, 100); - mainGrid->addWidget(hsplitter, 0, 1, 1, 3); - - // Original. - /* - mainGrid->setColumnStretch(1, 100); - mainGrid->addWidget(splitter, 0, 0, 1, 3); - mainGrid->addWidget(ctrl, 1, 0); - mainGrid->addWidget(hscroll, 1, 1); - mainGrid->addWidget(corner, 1, 2, Qt::AlignBottom|Qt::AlignRight); - */ - - - // Tim. - /* - mainGrid->setColumnStretch(2, 100); - mainGrid->addWidget(splitter, 0, 0, 1, 4); - mainGrid->addWidget(trackInfoButton, 1, 0); - mainGrid->addWidget(ctrl, 1, 1); - mainGrid->addWidget(hscroll, 1, 2); - mainGrid->addWidget(corner, 1, 3, Qt::AlignBottom|Qt::AlignRight); - */ - - //mainGrid->addRowSpacing(1, hscroll->sizeHint().height()); - //mainGrid->addItem(new QSpacerItem(0, hscroll->sizeHint().height()), 1, 0); // Orig + Tim. - - QWidget* split1 = new QWidget(splitter); - split1->setObjectName("split1"); - QGridLayout* gridS1 = new QGridLayout(split1); - gridS1->setContentsMargins(0, 0, 0, 0); - gridS1->setSpacing(0); - //Defined and configure your program change bar here. - //This may well be a copy of MTScale extended for our needs - time = new MTScale(&_raster, split1, xscale); - Piano* piano = new Piano(split1, yscale); - canvas = new PianoCanvas(this, split1, xscale, yscale); - vscroll = new ScrollScale(-3, 7, yscale, KH * 75, Qt::Vertical, split1); - - //setFocusProxy(canvas); // Tim. - - int offset = -(config.division/4); - canvas->setOrigin(offset, 0); - canvas->setCanvasTools(ScoreEditTools); - canvas->setFocus(); - connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int))); - time->setOrigin(offset, 0); - - gridS1->setRowStretch(2, 100); - gridS1->setColumnStretch(1, 100); - //gridS1->setColumnStretch(2, 100); // Tim. - - gridS1->addWidget(time, 0, 1, 1, 2); - gridS1->addWidget(hLine(split1), 1, 0, 1, 3); - gridS1->addWidget(piano, 2, 0); - gridS1->addWidget(canvas, 2, 1); - gridS1->addWidget(vscroll, 2, 2); - - // Tim. - /* - gridS1->addWidget(time, 0, 2, 1, 3); - gridS1->addWidget(hLine(split1), 1, 1, 1, 4); - //gridS1->addWidget(infoScroll, 2, 0); - gridS1->addWidget(infoScroll, 0, 0, 3, 1); - gridS1->addWidget(piano, 2, 1); - gridS1->addWidget(canvas, 2, 2); - gridS1->addWidget(vscroll, 2, 3); - */ - - ctrlLane = new Splitter(Qt::Vertical, splitter, "ctrllane"); - QWidget* split2 = new QWidget(splitter); - split2->setMaximumHeight(hscroll->sizeHint().height()); - split2->setMinimumHeight(hscroll->sizeHint().height()); - QGridLayout* gridS2 = new QGridLayout(split2); - gridS2->setContentsMargins(0, 0, 0, 0); - gridS2->setSpacing(0); - gridS2->setRowStretch(0, 100); - gridS2->setColumnStretch(1, 100); - gridS2->addWidget(ctrl, 0, 0); - gridS2->addWidget(hscroll, 0, 1); - gridS2->addWidget(corner, 0, 2, Qt::AlignBottom|Qt::AlignRight); - //splitter->setCollapsible(0, true); - - piano->setFixedWidth(pianoWidth); - - // Tim. - QList<int> mops; - mops.append(mtiw + 30); // 30 for possible scrollbar - mops.append(width() - mtiw - 30); - hsplitter->setSizes(mops); - - connect(tools2, SIGNAL(toolChanged(int)), canvas, SLOT(setTool(int))); - - connect(ctrl, SIGNAL(clicked()), SLOT(addCtrl())); - //connect(trackInfoButton, SIGNAL(clicked()), SLOT(toggleTrackInfo())); Tim. - connect(info, SIGNAL(valueChanged(NoteInfo::ValType, int)), SLOT(noteinfoChanged(NoteInfo::ValType, int))); - connect(vscroll, SIGNAL(scrollChanged(int)), piano, SLOT(setYPos(int))); - connect(vscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setYPos(int))); - connect(vscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setYMag(int))); - connect(vscroll, SIGNAL(scaleChanged(int)), piano, SLOT(setYMag(int))); - - connect(hscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setXPos(int))); - connect(hscroll, SIGNAL(scrollChanged(int)), time, SLOT(setXPos(int))); - - connect(hscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setXMag(int))); - connect(hscroll, SIGNAL(scaleChanged(int)), time, SLOT(setXMag(int))); - - connect(canvas, SIGNAL(newWidth(int)), SLOT(newCanvasWidth(int))); - connect(canvas, SIGNAL(pitchChanged(int)), piano, SLOT(setPitch(int))); - connect(canvas, SIGNAL(verticalScroll(unsigned)), vscroll, SLOT(setPos(unsigned))); - connect(canvas, SIGNAL(horizontalScroll(unsigned)),hscroll, SLOT(setPos(unsigned))); - connect(canvas, SIGNAL(horizontalScrollNoLimit(unsigned)),hscroll, SLOT(setPosNoLimit(unsigned))); - connect(canvas, SIGNAL(selectionChanged(int, Event&, Part*)), this, - SLOT(setSelection(int, Event&, Part*))); - - connect(piano, SIGNAL(keyPressed(int, int, bool)), canvas, SLOT(pianoPressed(int, int, bool))); - connect(piano, SIGNAL(keyReleased(int, bool)), canvas, SLOT(pianoReleased(int, bool))); - connect(srec, SIGNAL(toggled(bool)), SLOT(setSteprec(bool))); - connect(midiin, SIGNAL(toggled(bool)), canvas, SLOT(setMidiin(bool))); - connect(speaker, SIGNAL(toggled(bool)), SLOT(setSpeaker(bool))); - connect(canvas, SIGNAL(followEvent(int)), SLOT(follow(int))); - - connect(hscroll, SIGNAL(scaleChanged(int)), SLOT(updateHScrollRange())); - piano->setYPos(KH * 30); - canvas->setYPos(KH * 30); - vscroll->setPos(KH * 30); - //setSelection(0, 0, 0); //Really necessary? Causes segfault when only 1 item selected, replaced by the following: - info->setEnabled(false); - - connect(song, SIGNAL(songChanged(int)), SLOT(songChanged1(int))); - - setWindowTitle(canvas->getCaption()); - - updateHScrollRange(); - // connect to toolbar - connect(canvas, SIGNAL(pitchChanged(int)), toolbar, SLOT(setPitch(int))); - connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); - connect(piano, SIGNAL(pitchChanged(int)), toolbar, SLOT(setPitch(int))); - connect(time, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); - connect(toolbar, SIGNAL(quantChanged(int)), SLOT(setQuant(int))); - connect(toolbar, SIGNAL(rasterChanged(int)),SLOT(setRaster(int))); - connect(toolbar, SIGNAL(toChanged(int)), SLOT(setTo(int))); - connect(toolbar, SIGNAL(soloChanged(bool)), SLOT(soloChanged(bool))); - - setFocusPolicy(Qt::StrongFocus); - setEventColorMode(colorMode); - - QClipboard* cb = QApplication::clipboard(); - connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged())); - - clipboardChanged(); // enable/disable "Paste" - selectionChanged(); // enable/disable "Copy" & "Paste" - initShortcuts(); // initialize shortcuts - - const Pos cpos=song->cPos(); - canvas->setPos(0, cpos.tick(), true); - canvas->selectAtTick(cpos.tick()); - //canvas->selectFirst();// - - unsigned pos=0; - if(initPos >= MAXINT) - pos = song->cpos(); - if(pos > MAXINT) - pos = MAXINT; - if (pos) - hscroll->setOffset((int)pos); - - if(canvas->track()) - { - updateTrackInfo(); - toolbar->setSolo(canvas->track()->solo()); - } - - QSettings settings("MusE", "MusE-qt"); - //restoreGeometry(settings.value("ScoreEdit/geometry").toByteArray()); - restoreState(settings.value("ScoreEdit/windowState").toByteArray()); - - } + : MidiEditor(0, 0, pl, parent, name) +{ + score_canvas=new ScoreCanvas(this, mainw, 1, 1); + xscroll = new QScrollBar(Qt::Horizontal, mainw); + yscroll = new QScrollBar(Qt::Vertical, mainw); + + connect(xscroll, SIGNAL(valueChanged(int)), score_canvas, SLOT(x_scroll_event(int))); + connect(score_canvas, SIGNAL(xscroll_changed(int)), xscroll, SLOT(setValue(int))); + + connect(yscroll, SIGNAL(valueChanged(int)), score_canvas, SLOT(y_scroll_event(int))); + connect(score_canvas, SIGNAL(yscroll_changed(int)), yscroll, SLOT(setValue(int))); + + connect(score_canvas, SIGNAL(canvas_width_changed(int)), SLOT(canvas_width_changed(int))); + connect(score_canvas, SIGNAL(viewport_width_changed(int)), SLOT(viewport_width_changed(int))); + connect(score_canvas, SIGNAL(canvas_height_changed(int)), SLOT(canvas_height_changed(int))); + connect(score_canvas, SIGNAL(viewport_height_changed(int)), SLOT(viewport_height_changed(int))); + + connect(song, SIGNAL(songChanged(int)), score_canvas, SLOT(song_changed(int))); + + mainGrid->addWidget(score_canvas, 0, 0); + mainGrid->addWidget(xscroll,1,0); + mainGrid->addWidget(yscroll,0,1); + + xscroll->setMinimum(0); + yscroll->setMinimum(0); + + menu_mapper=new QSignalMapper(this); + connect(menu_mapper, SIGNAL(mapped(int)), SLOT(menu_command(int))); + + + + // Toolbars --------------------------------------------------------- + QToolBar* undo_tools=addToolBar(tr("Undo/Redo tools")); + undo_tools->setObjectName("Undo/Redo tools"); + undo_tools->addActions(undoRedo->actions()); + addToolBar(undo_tools); + + EditToolBar* edit_tools = new EditToolBar(this, PointerTool | PencilTool | RubberTool); + addToolBar(edit_tools); + edit_tools->set(PointerTool); + score_canvas->set_tool(PointerTool); + connect(edit_tools, SIGNAL(toolChanged(int)), score_canvas, SLOT(set_tool(int))); + + QToolBar* panic_toolbar = addToolBar(tr("panic")); + panic_toolbar->setObjectName("panic"); + panic_toolbar->addAction(panicAction); + + QToolBar* transport_toolbar = addToolBar(tr("transport")); + transport_toolbar->setObjectName("transport"); + transport_toolbar->addActions(transportAction->actions()); + + QToolBar* quant_len_toolbar = addToolBar(tr("Quant'n'length")); + quant_len_toolbar->setObjectName("Quant'n'length"); + quant_len_toolbar->addWidget(new QLabel(tr("Note length:"), quant_len_toolbar)); + QActionGroup* len_actions=new QActionGroup(this); + QAction* n1_action = quant_len_toolbar->addAction("1", menu_mapper, SLOT(map())); + QAction* n2_action = quant_len_toolbar->addAction("2", menu_mapper, SLOT(map())); + QAction* n4_action = quant_len_toolbar->addAction("4", menu_mapper, SLOT(map())); + QAction* n8_action = quant_len_toolbar->addAction("8", menu_mapper, SLOT(map())); + QAction* n16_action = quant_len_toolbar->addAction("16", menu_mapper, SLOT(map())); + QAction* n32_action = quant_len_toolbar->addAction("32", menu_mapper, SLOT(map())); + QAction* nlast_action = quant_len_toolbar->addAction(tr("last"), menu_mapper, SLOT(map())); + menu_mapper->setMapping(n1_action, CMD_NOTELEN_1); + menu_mapper->setMapping(n2_action, CMD_NOTELEN_2); + menu_mapper->setMapping(n4_action, CMD_NOTELEN_4); + menu_mapper->setMapping(n8_action, CMD_NOTELEN_8); + menu_mapper->setMapping(n16_action, CMD_NOTELEN_16); + menu_mapper->setMapping(n32_action, CMD_NOTELEN_32); + menu_mapper->setMapping(nlast_action, CMD_NOTELEN_LAST); + n1_action->setCheckable(true); + n2_action->setCheckable(true); + n4_action->setCheckable(true); + n8_action->setCheckable(true); + n16_action->setCheckable(true); + n32_action->setCheckable(true); + nlast_action->setCheckable(true); + len_actions->addAction(n1_action); + len_actions->addAction(n2_action); + len_actions->addAction(n4_action); + len_actions->addAction(n8_action); + len_actions->addAction(n16_action); + len_actions->addAction(n32_action); + len_actions->addAction(nlast_action); + + nlast_action->setChecked(true); + menu_command(CMD_NOTELEN_LAST); + + quant_len_toolbar->addSeparator(); + quant_len_toolbar->addWidget(new QLabel(tr("Quantisation:"), quant_len_toolbar)); + QComboBox* quant_combobox = new QComboBox(this); + quant_combobox->addItem("2"); // if you add or remove items from + quant_combobox->addItem("4"); // here, also change quant_mapper[] + quant_combobox->addItem("8"); // in ScoreCanvas::set_quant()! + quant_combobox->addItem("16"); + quant_combobox->addItem("32"); + connect(quant_combobox, SIGNAL(currentIndexChanged(int)), score_canvas, SLOT(set_quant(int))); + quant_len_toolbar->addWidget(quant_combobox); + quant_combobox->setCurrentIndex(2); + + + QMenu* settings_menu = menuBar()->addMenu(tr("&Settings")); + + QMenu* color_menu = settings_menu->addMenu(tr("Note head &colors")); + QActionGroup* color_actions = new QActionGroup(this); + QAction* color_black_action = color_menu->addAction(tr("&Black"), menu_mapper, SLOT(map())); + QAction* color_velo_action = color_menu->addAction(tr("&Velocity"), menu_mapper, SLOT(map())); + QAction* color_part_action = color_menu->addAction(tr("&Part"), menu_mapper, SLOT(map())); + color_black_action->setCheckable(true); + color_velo_action->setCheckable(true); + color_part_action->setCheckable(true); + color_actions->addAction(color_black_action); + color_actions->addAction(color_velo_action); + color_actions->addAction(color_part_action); + menu_mapper->setMapping(color_black_action, CMD_COLOR_BLACK); + menu_mapper->setMapping(color_velo_action, CMD_COLOR_VELO); + menu_mapper->setMapping(color_part_action, CMD_COLOR_PART); + + color_black_action->setChecked(true); + menu_command(CMD_COLOR_BLACK); + + QMenu* preamble_menu = settings_menu->addMenu(tr("Set up &preamble")); + QAction* preamble_keysig_action = preamble_menu->addAction(tr("Display &key signature")); + QAction* preamble_timesig_action = preamble_menu->addAction(tr("Display &time signature")); + connect(preamble_keysig_action, SIGNAL(toggled(bool)), score_canvas, SLOT(preamble_keysig_slot(bool))); + connect(preamble_timesig_action, SIGNAL(toggled(bool)), score_canvas, SLOT(preamble_timesig_slot(bool))); + + preamble_keysig_action->setCheckable(true); + preamble_timesig_action->setCheckable(true); + + preamble_keysig_action->setChecked(true); + preamble_timesig_action->setChecked(true); + + QAction* set_name_action = settings_menu->addAction(tr("Set Score &name"), menu_mapper, SLOT(map())); + menu_mapper->setMapping(set_name_action, CMD_SET_NAME); + + + + +/* FINDMICHJETZT + addToolBarBreak(); + info = new NoteInfo(this); + addToolBar(info); +*/ -//--------------------------------------------------------- -// songChanged1 -//--------------------------------------------------------- -void ScoreEdit::songChanged1(int bits) - { - - if (bits & SC_SOLO) - { - toolbar->setSolo(canvas->track()->solo()); - return; - } - songChanged(bits); - //trackInfo->songChanged(bits); - // We'll receive SC_SELECTION if a different part is selected. - if (bits & SC_SELECTION) - updateTrackInfo(); - } -//--------------------------------------------------------- -// configChanged -//--------------------------------------------------------- -void ScoreEdit::configChanged() - { - initShortcuts(); - //trackInfo->updateTrackInfo(); - } + score_canvas->song_changed(SC_EVENT_INSERTED); + score_canvas->goto_tick(initPos,true); + + if (name!=NULL) + set_name(name, false, true); + else + set_name("Score "+IntToQStr(serial++), false, true); +} -//--------------------------------------------------------- -// updateHScrollRange -//--------------------------------------------------------- -void ScoreEdit::updateHScrollRange() +void ScoreEdit::add_parts(PartList* pl, bool all_in_one) { - int s, e; - canvas->range(&s, &e); - // Show one more measure. - e += AL::sigmap.ticksMeasure(e); - // Show another quarter measure due to imprecise drawing at canvas end point. - e += AL::sigmap.ticksMeasure(e) / 4; - // Compensate for the fixed piano and vscroll widths. - e += canvas->rmapxDev(pianoWidth - vscroll->width()); - int s1, e1; - hscroll->range(&s1, &e1); - if(s != s1 || e != e1) - hscroll->setRange(s, e); + score_canvas->add_staves(pl, all_in_one); } -void ScoreEdit::updateTrackInfo() +bool ScoreEdit::set_name(QString newname, bool emit_signal, bool emergency_name) { - selected = curCanvasPart()->track(); - if (selected->isMidiTrack()) { - midiTrackInfo->setTrack(selected); - ///midiTrackInfo->updateTrackInfo(-1); - } + if (names.find(newname)==names.end()) + { + names.erase(name); + names.insert(newname); + + name=newname; + + if (emit_signal) + emit name_changed(); + + return true; + } + else + { + if (emergency_name) + { + while (set_name(create_random_string(), emit_signal, false) == false); + return true; + } + else + return false; + } } //--------------------------------------------------------- -// follow +// ~ScoreEdit //--------------------------------------------------------- -void ScoreEdit::follow(int pos) - { - int s, e; - canvas->range(&s, &e); +ScoreEdit::~ScoreEdit() +{ + +} + - if (pos < e && pos >= s) - hscroll->setOffset(pos); - if (pos < s) - hscroll->setOffset(s); - } +void ScoreEdit::canvas_width_changed(int width) +{ + xscroll->setMaximum(width); +} +void ScoreEdit::viewport_width_changed(int width) +{ + xscroll->setPageStep(width * PAGESTEP); +} -//--------------------------------------------------------- -// setTime -//--------------------------------------------------------- +void ScoreEdit::canvas_height_changed(int height) +{ + int val=height - score_canvas->viewport_height(); + if (val<=0) val=0; + + yscroll->setMaximum(val); + + if (val==0) + yscroll->hide(); + else + yscroll->show(); +} +void ScoreEdit::viewport_height_changed(int height) +{ + int val=score_canvas->canvas_height() - height; + if (val<0) val=0; + yscroll->setPageStep(height * PAGESTEP); + yscroll->setMaximum(val); + + if (val==0) + yscroll->hide(); + else + yscroll->show(); +} -void ScoreEdit::setTime(unsigned tick) - { - toolbar->setTime(tick); - time->setPos(3, tick, false); - } +void ScoreEdit::closeEvent(QCloseEvent* e) +{ + QSettings settings("MusE", "MusE-qt"); + //settings.setValue("ScoreEdit/geometry", saveGeometry()); + settings.setValue("ScoreEdit/windowState", saveState()); -//--------------------------------------------------------- -// ~ScoreEdit -//--------------------------------------------------------- + emit deleted((unsigned long)this); + e->accept(); +} -ScoreEdit::~ScoreEdit() - { - // undoRedo->removeFrom(tools); // p4.0.6 Removed - } +void ScoreEdit::menu_command(int cmd) +{ + switch (cmd) + { + case CMD_SET_NAME: + { + bool ok; + QString newname = QInputDialog::getText(this, tr("Enter the new score title"), + tr("Enter the new score title"), QLineEdit::Normal, + name, &ok); + if (ok) + { + if (!set_name(newname)) + QMessageBox::warning(this, tr("Error"), tr("Changing score title failed:\nthe selected title is not unique")); + } + } + + default: + score_canvas->menu_command(cmd); + } +} -//--------------------------------------------------------- -// cmd -// pulldown menu commands -//--------------------------------------------------------- -void ScoreEdit::cmd(int cmd) - { - ((PianoCanvas*)canvas)->cmd(cmd, _quantStrength, _quantLimit, _quantLen, _to); - } -//--------------------------------------------------------- -// setSelection -// update Info Line -//--------------------------------------------------------- +void ScoreCanvas::add_staves(PartList* pl, bool all_in_one) +{ + staff_t staff(this); + + if (all_in_one) + { + staff.parts.clear(); + for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) + staff.parts.insert(part_it->second); + + staff.split_note=SPLIT_NOTE; + + staff.type=GRAND_TOP; //FINDMICH + staff.clef=VIOLIN; + staves.push_back(staff); + + staff.type=GRAND_BOTTOM; + staff.clef=BASS; + staves.push_back(staff); + } + else + { + set<Track*> tracks; + + for (ciPart it=pl->begin(); it!=pl->end(); it++) + tracks.insert(it->second->track()); + + for (set<Track*>::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + staff.parts.clear(); + for (ciPart part_it=pl->begin(); part_it!=pl->end(); part_it++) + if (part_it->second->track() == *it) + staff.parts.insert(part_it->second); + + staff.split_note=SPLIT_NOTE; + + staff.type=GRAND_TOP; //FINDMICH + staff.clef=VIOLIN; + staves.push_back(staff); + + staff.type=GRAND_BOTTOM; + staff.clef=BASS; + staves.push_back(staff); + } + } + + recalc_staff_pos(); + song_changed(SC_EVENT_INSERTED); +} -void ScoreEdit::setSelection(int tick, Event& e, Part* p) - { - int selections = canvas->selectionSize(); - - selEvent = e; - selPart = (MidiPart*)p; - selTick = tick; - - if (selections > 1) { - info->setEnabled(true); - info->setDeltaMode(true); - if (!deltaMode) { - deltaMode = true; - info->setValues(0, 0, 0, 0, 0); - tickOffset = 0; - lenOffset = 0; - pitchOffset = 0; - veloOnOffset = 0; - veloOffOffset = 0; - } - } - else if (selections == 1) { - deltaMode = false; - info->setEnabled(true); - info->setDeltaMode(false); - info->setValues(tick, - selEvent.lenTick(), - selEvent.pitch(), - selEvent.velo(), - selEvent.veloOff()); - } - else { - deltaMode = false; - info->setEnabled(false); - } - selectionChanged(); - } -//--------------------------------------------------------- -// edit currently selected Event -//--------------------------------------------------------- +ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent, + int sx, int sy) : View(parent, sx, sy) +{ + editor = pr; + setFocusPolicy(Qt::StrongFocus); + setBg(Qt::white); + + setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + + load_pixmaps(); + + x_pos=0; + x_left=0; + y_pos=0; + dragging=false; + mouse_erases_notes=false; + mouse_inserts_notes=true; + + curr_part=editor->parts()->begin()->second; //TODO FINDMICHJETZT + + last_len=384; + new_len=-1; + + set_quant(2); //this is actually unneccessary, as while + //initalizing the quant_combobox, this gets + //called again. but for safety... + + dragging_staff=false; + + + coloring_mode=COLOR_MODE_BLACK; + preamble_contains_keysig=true; + preamble_contains_timesig=true; + + + x_scroll_speed=0; + x_scroll_pos=0; + y_scroll_speed=0; + y_scroll_pos=0; + connect (heartBeatTimer, SIGNAL(timeout()), SLOT(heartbeat_timer_event())); + + connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(pos_changed(int,unsigned,bool))); + connect(song, SIGNAL(playChanged(bool)), SLOT(play_changed(bool))); + connect(muse, SIGNAL(configChanged()), SLOT(config_changed())); + + + staff_menu=new QMenu(this); + + staffmode_treble_action = staff_menu->addAction(tr("Treble")); + connect(staffmode_treble_action, SIGNAL(triggered()), SLOT(staffmode_treble_slot())); + + staffmode_bass_action = staff_menu->addAction(tr("Bass")); + connect(staffmode_bass_action, SIGNAL(triggered()), SLOT(staffmode_bass_slot())); + + staffmode_both_action = staff_menu->addAction(tr("Grand Staff")); + connect(staffmode_both_action, SIGNAL(triggered()), SLOT(staffmode_both_slot())); + + remove_staff_action = staff_menu->addAction(tr("Remove staff")); + connect(remove_staff_action, SIGNAL(triggered()), SLOT(remove_staff_slot())); -void ScoreEdit::noteinfoChanged(NoteInfo::ValType type, int val) - { - int selections = canvas->selectionSize(); - - if (selections == 0) { - printf("noteinfoChanged while nothing selected\n"); - } - else if (selections == 1) { - Event event = selEvent.clone(); - switch(type) { - case NoteInfo::VAL_TIME: - event.setTick(val - selPart->tick()); - break; - case NoteInfo::VAL_LEN: - event.setLenTick(val); - break; - case NoteInfo::VAL_VELON: - event.setVelo(val); - break; - case NoteInfo::VAL_VELOFF: - event.setVeloOff(val); - break; - case NoteInfo::VAL_PITCH: - event.setPitch(val); - break; - } - // Indicate do undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(selEvent, event, selPart); - audio->msgChangeEvent(selEvent, event, selPart, true, false, false); - } - else { - // multiple events are selected; treat noteinfo values - // as offsets to event values - - int delta = 0; - switch (type) { - case NoteInfo::VAL_TIME: - delta = val - tickOffset; - tickOffset = val; - break; - case NoteInfo::VAL_LEN: - delta = val - lenOffset; - lenOffset = val; - break; - case NoteInfo::VAL_VELON: - delta = val - veloOnOffset; - veloOnOffset = val; - break; - case NoteInfo::VAL_VELOFF: - delta = val - veloOffOffset; - veloOffOffset = val; - break; - case NoteInfo::VAL_PITCH: - delta = val - pitchOffset; - pitchOffset = val; - break; - } - if (delta) - canvas->modifySelected(type, delta); - } - } +} -//--------------------------------------------------------- -// addCtrl -//--------------------------------------------------------- +void ScoreCanvas::staffmode_treble_slot() +{ + set_staffmode(current_staff, MODE_TREBLE); +} -CtrlEdit* ScoreEdit::addCtrl() - { - ///CtrlEdit* ctrlEdit = new CtrlEdit(splitter, this, xscale, false, "pianoCtrlEdit"); - CtrlEdit* ctrlEdit = new CtrlEdit(ctrlLane/*splitter*/, this, xscale, false, "pianoCtrlEdit"); // ccharrett - connect(tools2, SIGNAL(toolChanged(int)), ctrlEdit, SLOT(setTool(int))); - connect(hscroll, SIGNAL(scrollChanged(int)), ctrlEdit, SLOT(setXPos(int))); - connect(hscroll, SIGNAL(scaleChanged(int)), ctrlEdit, SLOT(setXMag(int))); - connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); - connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*))); - connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int))); - - ctrlEdit->setTool(tools2->curTool()); - ctrlEdit->setXPos(hscroll->pos()); - ctrlEdit->setXMag(hscroll->getScaleValue()); - - ctrlEdit->show(); - ctrlEditList.push_back(ctrlEdit); - return ctrlEdit; - } +void ScoreCanvas::staffmode_bass_slot() +{ + set_staffmode(current_staff, MODE_BASS); +} -//--------------------------------------------------------- -// removeCtrl -//--------------------------------------------------------- +void ScoreCanvas::staffmode_both_slot() +{ + set_staffmode(current_staff, MODE_BOTH); +} -void ScoreEdit::removeCtrl(CtrlEdit* ctrl) - { - for (std::list<CtrlEdit*>::iterator i = ctrlEditList.begin(); - i != ctrlEditList.end(); ++i) { - if (*i == ctrl) { - ctrlEditList.erase(i); - break; - } - } - } +void ScoreCanvas::remove_staff_slot() +{ + remove_staff(current_staff); +} -//--------------------------------------------------------- -// closeEvent -//--------------------------------------------------------- +void ScoreCanvas::set_staffmode(list<staff_t>::iterator it, staff_mode_t mode) +{ + if (it->type == GRAND_BOTTOM) + { + it--; + if (it->type!=GRAND_TOP) + cout << "THIS SHOULD NEVER HAPPEN: grand_bottom without top!"<<endl; + } + + if (it->type==GRAND_TOP) + { + list<staff_t>::iterator tmp=it; + tmp++; + if (tmp->type!=GRAND_BOTTOM) + cout << "THIS SHOULD NEVER HAPPEN: grand_top without bottom!"<<endl; + staves.erase(tmp); + } + + switch (mode) + { + case MODE_TREBLE: + it->type=NORMAL; + it->clef=VIOLIN; + break; + + case MODE_BASS: + it->type=NORMAL; + it->clef=BASS; + break; + + case MODE_BOTH: + it->type=GRAND_BOTTOM; + it->clef=BASS; + it->split_note=SPLIT_NOTE; + + staves.insert(it, staff_t(this, GRAND_TOP, VIOLIN, it->parts, it->split_note)); + break; + + default: + cout << "ILLEGAL FUNCTION CALL: invalid mode in set_staffmode" << endl; + } + + recalc_staff_pos(); + song_changed(SC_EVENT_INSERTED); +} -void ScoreEdit::closeEvent(QCloseEvent* e) - { - QSettings settings("MusE", "MusE-qt"); - //settings.setValue("ScoreEdit/geometry", saveGeometry()); - settings.setValue("ScoreEdit/windowState", saveState()); +void ScoreCanvas::remove_staff(list<staff_t>::iterator it) +{ + if (it->type == GRAND_BOTTOM) + { + it--; + if (it->type!=GRAND_TOP) + cout << "THIS SHOULD NEVER HAPPEN: grand_bottom without top!"<<endl; + } + + if (it->type == NORMAL) + { + staves.erase(it); + } + else if (it->type == GRAND_TOP) + { + staves.erase(it++); + if (it->type!=GRAND_BOTTOM) + cout << "THIS SHOULD NEVER HAPPEN: grand_top without bottom!"<<endl; + staves.erase(it); + } + + recalc_staff_pos(); + song_changed(SC_EVENT_INSERTED); +} + +void ScoreCanvas::merge_staves(list<staff_t>::iterator dest, list<staff_t>::iterator src) +{ + if (dest->type == GRAND_BOTTOM) + { + dest--; + if (dest->type!=GRAND_TOP) + cout << "THIS SHOULD NEVER HAPPEN: grand_bottom without top!"<<endl; + } + + if (src->type == GRAND_BOTTOM) + { + src--; + if (src->type!=GRAND_TOP) + cout << "THIS SHOULD NEVER HAPPEN: grand_bottom without top!"<<endl; + } + + if (dest==src) //dragged to itself? + return; + + + dest->parts.insert(src->parts.begin(), src->parts.end()); + + if (dest->type == GRAND_TOP) + { + dest++; + if (dest->type != GRAND_BOTTOM) + cout << "THIS SHOULD NEVER HAPPEN: grand_top without bottom!"<<endl; + dest->parts.insert(src->parts.begin(), src->parts.end()); + } + + remove_staff(src); + + recalc_staff_pos(); + song_changed(SC_EVENT_INSERTED); +} - emit deleted((unsigned long)this); - e->accept(); - } -//--------------------------------------------------------- -// readConfiguration -//--------------------------------------------------------- +void ScoreCanvas::song_changed(int flags) +{ + if (flags & (SC_PART_INSERTED | SC_PART_MODIFIED | SC_PART_REMOVED | + SC_EVENT_INSERTED | SC_EVENT_MODIFIED | SC_EVENT_REMOVED | + SC_SIG | SC_KEY) ) + { + cout << "song changed!" << endl; + + calc_pos_add_list(); + + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + { + it->create_appropriate_eventlist(it->parts); + it->create_itemlist(); + it->process_itemlist(); // do note- and rest-grouping and collision avoiding + it->calc_item_pos(); + } + + redraw(); + cout << "song had changed, recalculation complete" << endl; + + emit canvas_width_changed(canvas_width()); + } +} -void ScoreEdit::readConfiguration(Xml& xml) - { - for (;;) { - Xml::Token token = xml.parse(); - if (token == Xml::Error || token == Xml::End) - break; - const QString& tag = xml.s1(); - switch (token) { - case Xml::TagStart: - if (tag == "quant") - _quantInit = xml.parseInt(); - else if (tag == "raster") - _rasterInit = xml.parseInt(); - else if (tag == "quantStrength") - _quantStrengthInit = xml.parseInt(); - else if (tag == "quantLimit") - _quantLimitInit = xml.parseInt(); - else if (tag == "quantLen") - _quantLenInit = xml.parseInt(); - else if (tag == "to") - _toInit = xml.parseInt(); - else if (tag == "colormode") - colorModeInit = xml.parseInt(); - else if (tag == "width") - _widthInit = xml.parseInt(); - else if (tag == "height") - _heightInit = xml.parseInt(); - else - xml.unknown("ScoreEdit"); - break; - case Xml::TagEnd: - if (tag == "ScoreEdit") - return; - default: - break; - } - } - } +int ScoreCanvas::canvas_width() +{ + //return tick_to_x(staves.begin()->itemlist.rbegin()->first); + return tick_to_x(SONG_LENGTH); +} -//--------------------------------------------------------- -// writeConfiguration -//--------------------------------------------------------- +int ScoreCanvas::canvas_height() +{ + return staves.rbegin()->y_bottom; +} -void ScoreEdit::writeConfiguration(int level, Xml& xml) - { - xml.tag(level++, "ScoreEdit"); - xml.intTag(level, "quant", _quantInit); - xml.intTag(level, "raster", _rasterInit); - xml.intTag(level, "quantStrength", _quantStrengthInit); - xml.intTag(level, "quantLimit", _quantLimitInit); - xml.intTag(level, "quantLen", _quantLenInit); - xml.intTag(level, "to", _toInit); - xml.intTag(level, "width", _widthInit); - xml.intTag(level, "height", _heightInit); - xml.intTag(level, "colormode", colorModeInit); - xml.etag(level, "ScoreEdit"); - } +int ScoreCanvas::viewport_width() +{ + return (width() - x_left); +} -//--------------------------------------------------------- -// soloChanged -// signal from solo button -//--------------------------------------------------------- +int ScoreCanvas::viewport_height() +{ + return height(); +} -void ScoreEdit::soloChanged(bool flag) - { - audio->msgSetSolo(canvas->track(), flag); - song->update(SC_SOLO); - } +string IntToStr(int i) +{ + ostringstream s; + s<<i; + return s.str(); +} -//--------------------------------------------------------- -// setRaster -//--------------------------------------------------------- +QString IntToQStr(int i) +{ + return QString(IntToStr(i).c_str()); +} -void ScoreEdit::setRaster(int val) - { - _rasterInit = val; - MidiEditor::setRaster(val); - canvas->redrawGrid(); - canvas->setFocus(); // give back focus after kb input - } +void color_image(QImage& img, const QColor& color) +{ + uchar* ptr=img.bits(); + int bytes=img.byteCount(); + int r,g,b; + color.getRgb(&r,&g,&b); + + for (int i=0; i<bytes/4; i++) + { + QRgb* rgb=((QRgb*)ptr); + (*rgb) = qRgba(r,g,b,qAlpha(*rgb)); + + ptr+=4; + } +} -//--------------------------------------------------------- -// setQuant -//--------------------------------------------------------- +void load_colored_pixmaps(QString file, QPixmap* array) +{ + QImage img(file); + + color_image(img, Qt::black); + array[BLACK_PIXMAP]=QPixmap::fromImage(img); + + color_image(img, Qt::red); + array[HIGHLIGHTED_PIXMAP]=QPixmap::fromImage(img); + + + for (int color_index=0;color_index<NUM_PARTCOLORS; color_index++) + { + color_image(img, config.partColors[color_index]); + array[color_index]=QPixmap::fromImage(img); + } +} -void ScoreEdit::setQuant(int val) - { - _quantInit = val; - MidiEditor::setQuant(val); - canvas->setFocus(); - } -//--------------------------------------------------------- -// writeStatus -//--------------------------------------------------------- -void ScoreEdit::writeStatus(int level, Xml& xml) const - { - writePartList(level, xml); - xml.tag(level++, "ScoreEdit"); - MidiEditor::writeStatus(level, xml); - splitter->writeStatus(level, xml); - hsplitter->writeStatus(level, xml); - - for (std::list<CtrlEdit*>::const_iterator i = ctrlEditList.begin(); - i != ctrlEditList.end(); ++i) { - (*i)->writeStatus(level, xml); - } - - xml.intTag(level, "steprec", canvas->steprec()); - xml.intTag(level, "midiin", canvas->midiin()); - xml.intTag(level, "tool", int(canvas->tool())); - xml.intTag(level, "quantStrength", _quantStrength); - xml.intTag(level, "quantLimit", _quantLimit); - xml.intTag(level, "quantLen", _quantLen); - xml.intTag(level, "playEvents", _playEvents); - xml.intTag(level, "xpos", hscroll->pos()); - xml.intTag(level, "xmag", hscroll->mag()); - xml.intTag(level, "ypos", vscroll->pos()); - xml.intTag(level, "ymag", vscroll->mag()); - xml.tag(level, "/ScoreEdit"); - } +void ScoreCanvas::load_pixmaps() +{ + if (!pixmaps_loaded) + { + cout << "loading pixmaps..." << endl; + + pix_whole=new QPixmap[NUM_PARTCOLORS+2]; + pix_half=new QPixmap[NUM_PARTCOLORS+2]; + pix_quarter=new QPixmap[NUM_PARTCOLORS+2]; + pix_dot=new QPixmap[NUM_PARTCOLORS+2]; + pix_b=new QPixmap[NUM_PARTCOLORS+2]; + pix_sharp=new QPixmap[NUM_PARTCOLORS+2]; + pix_noacc=new QPixmap[NUM_PARTCOLORS+2]; + pix_num=new QPixmap[10]; + + pix_r1=new QPixmap; + pix_r2=new QPixmap; + pix_r4=new QPixmap; + pix_r8=new QPixmap; + pix_r16=new QPixmap; + + pix_clef_violin=new QPixmap; + pix_clef_bass=new QPixmap; + + pix_flag_up=new QPixmap[4]; + pix_flag_down=new QPixmap[4]; + + + + + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/whole.png", pix_whole); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/half.png", pix_half); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/quarter.png", pix_quarter); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/dot.png", pix_dot); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/acc_none.png", pix_noacc); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/acc_sharp.png", pix_sharp); + load_colored_pixmaps(museGlobalShare + "/scoreglyphs/acc_b.png", pix_b); + + pix_r1->load(museGlobalShare + "/scoreglyphs/rest1.png"); + pix_r2->load(museGlobalShare + "/scoreglyphs/rest2.png"); + pix_r4->load(museGlobalShare + "/scoreglyphs/rest4.png"); + pix_r8->load(museGlobalShare + "/scoreglyphs/rest8.png"); + pix_r16->load(museGlobalShare + "/scoreglyphs/rest16.png"); + pix_flag_up[0].load(museGlobalShare + "/scoreglyphs/flags8u.png"); + pix_flag_up[1].load(museGlobalShare + "/scoreglyphs/flags16u.png"); + pix_flag_up[2].load(museGlobalShare + "/scoreglyphs/flags32u.png"); + pix_flag_up[3].load(museGlobalShare + "/scoreglyphs/flags64u.png"); + pix_flag_down[0].load(museGlobalShare + "/scoreglyphs/flags8d.png"); + pix_flag_down[1].load(museGlobalShare + "/scoreglyphs/flags16d.png"); + pix_flag_down[2].load(museGlobalShare + "/scoreglyphs/flags32d.png"); + pix_flag_down[3].load(museGlobalShare + "/scoreglyphs/flags64d.png"); + + pix_clef_violin->load(museGlobalShare + "/scoreglyphs/clef_violin_big.png"); + pix_clef_bass->load(museGlobalShare + "/scoreglyphs/clef_bass_big.png"); + + for (int i=0;i<10;i++) + pix_num[i].load(museGlobalShare + "/scoreglyphs/"+IntToQStr(i)+".png"); + + pixmaps_loaded=true; + } +} -//--------------------------------------------------------- -// readStatus -//--------------------------------------------------------- -void ScoreEdit::readStatus(Xml& xml) - { - for (;;) { - Xml::Token token = xml.parse(); - if (token == Xml::Error || token == Xml::End) - break; - const QString& tag = xml.s1(); - switch (token) { - case Xml::TagStart: - if (tag == "steprec") { - int val = xml.parseInt(); - canvas->setSteprec(val); - srec->setChecked(val); - } - else if (tag == "midiin") { - int val = xml.parseInt(); - canvas->setMidiin(val); - midiin->setChecked(val); - } - else if (tag == "tool") { - int tool = xml.parseInt(); - canvas->setTool(tool); - tools2->set(tool); - } - else if (tag == "midieditor") - MidiEditor::readStatus(xml); - else if (tag == "ctrledit") { - CtrlEdit* ctrl = addCtrl(); - ctrl->readStatus(xml); - } - else if (tag == splitter->objectName()) - splitter->readStatus(xml); - else if (tag == hsplitter->objectName()) - hsplitter->readStatus(xml); - else if (tag == "quantStrength") - _quantStrength = xml.parseInt(); - else if (tag == "quantLimit") - _quantLimit = xml.parseInt(); - else if (tag == "quantLen") - _quantLen = xml.parseInt(); - else if (tag == "playEvents") { - _playEvents = xml.parseInt(); - canvas->playEvents(_playEvents); - speaker->setChecked(_playEvents); - } - else if (tag == "xmag") - hscroll->setMag(xml.parseInt()); - else if (tag == "xpos") - hscroll->setPos(xml.parseInt()); - else if (tag == "ymag") - vscroll->setMag(xml.parseInt()); - else if (tag == "ypos") - vscroll->setPos(xml.parseInt()); - else - xml.unknown("ScoreEdit"); - break; - case Xml::TagEnd: - if (tag == "ScoreEdit") { - _quantInit = _quant; - _rasterInit = _raster; - toolbar->setRaster(_raster); - toolbar->setQuant(_quant); - canvas->redrawGrid(); - return; - } - default: - break; - } - } - } - -static int rasterTable[] = { - //-9----8- 7 6 5 4 3(1/4) 2 1 - 4, 8, 16, 32, 64, 128, 256, 512, 1024, // triple - 6, 12, 24, 48, 96, 192, 384, 768, 1536, - 9, 18, 36, 72, 144, 288, 576, 1152, 2304 // dot - }; -//--------------------------------------------------------- -// viewKeyPressEvent -//--------------------------------------------------------- +int modulo(int a, int b) // similar to a % b +{ + return (((a%b)+b)%b); +} -void ScoreEdit::keyPressEvent(QKeyEvent* event) - { - if (info->hasFocus()) { - event->ignore(); - return; - } - - int index; - int n = sizeof(rasterTable)/sizeof(*rasterTable); - for (index = 0; index < n; ++index) - if (rasterTable[index] == raster()) - break; - if (index == n) { - index = 0; - // raster 1 is not in table - } - int off = (index / 9) * 9; - index = index % 9; - - int val = 0; - - PianoCanvas* pc = (PianoCanvas*)canvas; - int key = event->key(); - - //if (event->state() & Qt::ShiftButton) - if (((QInputEvent*)event)->modifiers() & Qt::ShiftModifier) - key += Qt::SHIFT; - //if (event->state() & Qt::AltButton) - if (((QInputEvent*)event)->modifiers() & Qt::AltModifier) - key += Qt::ALT; - //if (event->state() & Qt::ControlButton) - if (((QInputEvent*)event)->modifiers() & Qt::ControlModifier) - key+= Qt::CTRL; - - if (key == Qt::Key_Escape) { - close(); - return; - } - else if (key == shortcuts[SHRT_TOOL_POINTER].key) { - tools2->set(PointerTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_PENCIL].key) { - tools2->set(PencilTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_RUBBER].key) { - tools2->set(RubberTool); - return; - } - else if (key == shortcuts[SHRT_TOOL_LINEDRAW].key) { - tools2->set(DrawTool); - return; - } - else if (key == shortcuts[SHRT_POS_INC].key) { - pc->pianoCmd(CMD_RIGHT); - return; - } - else if (key == shortcuts[SHRT_POS_DEC].key) { - pc->pianoCmd(CMD_LEFT); - return; - } - else if (key == shortcuts[SHRT_POS_INC_NOSNAP].key) { - pc->pianoCmd(CMD_RIGHT_NOSNAP); - return; - } - else if (key == shortcuts[SHRT_POS_DEC_NOSNAP].key) { - pc->pianoCmd(CMD_LEFT_NOSNAP); - return; - } - else if (key == shortcuts[SHRT_INSERT_AT_LOCATION].key) { - pc->pianoCmd(CMD_INSERT); - return; - } - else if (key == Qt::Key_Delete) { - pc->pianoCmd(CMD_DELETE); - return; - } - else if (key == shortcuts[SHRT_ZOOM_IN].key) { - int mag = hscroll->mag(); - int zoomlvl = ScrollScale::getQuickZoomLevel(mag); - if (zoomlvl < 23) - zoomlvl++; - - int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl); - hscroll->setMag(newmag); - //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag); - return; - } - else if (key == shortcuts[SHRT_ZOOM_OUT].key) { - int mag = hscroll->mag(); - int zoomlvl = ScrollScale::getQuickZoomLevel(mag); - if (zoomlvl > 1) - zoomlvl--; - - int newmag = ScrollScale::convertQuickZoomLevelToMag(zoomlvl); - hscroll->setMag(newmag); - //printf("mag = %d zoomlvl = %d newmag = %d\n", mag, zoomlvl, newmag); - return; - } - else if (key == shortcuts[SHRT_GOTO_CPOS].key) { - PartList* p = this->parts(); - Part* first = p->begin()->second; - hscroll->setPos(song->cpos() - first->tick() ); - return; - } - else if (key == shortcuts[SHRT_SCROLL_LEFT].key) { - int pos = hscroll->pos() - config.division; - if (pos < 0) - pos = 0; - hscroll->setPos(pos); - return; - } - else if (key == shortcuts[SHRT_SCROLL_RIGHT].key) { - int pos = hscroll->pos() + config.division; - hscroll->setPos(pos); - return; - } - else if (key == shortcuts[SHRT_SET_QUANT_1].key) - val = rasterTable[8 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_2].key) - val = rasterTable[7 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_3].key) - val = rasterTable[6 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_4].key) - val = rasterTable[5 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_5].key) - val = rasterTable[4 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_6].key) - val = rasterTable[3 + off]; - else if (key == shortcuts[SHRT_SET_QUANT_7].key) - val = rasterTable[2 + off]; - else if (key == shortcuts[SHRT_TOGGLE_TRIOL].key) - val = rasterTable[index + ((off == 0) ? 9 : 0)]; - else if (key == shortcuts[SHRT_EVENT_COLOR].key) { - if (colorMode == 0) - colorMode = 1; - else if (colorMode == 1) - colorMode = 2; - else - colorMode = 0; - setEventColorMode(colorMode); - return; - } - else if (key == shortcuts[SHRT_TOGGLE_PUNCT].key) - val = rasterTable[index + ((off == 18) ? 9 : 18)]; - - else if (key == shortcuts[SHRT_TOGGLE_PUNCT2].key) {//CDW - if ((off == 18) && (index > 2)) { - val = rasterTable[index + 9 - 1]; - } - else if ((off == 9) && (index < 8)) { - val = rasterTable[index + 18 + 1]; - } - else - return; - } - else { //Default: - event->ignore(); - return; - } - setQuant(val); - setRaster(val); - toolbar->setQuant(_quant); - toolbar->setRaster(_raster); - } +int divide_floor(int a, int b) // similar to a / b +{ //TODO can be done better :/ + return int(floor(float(a)/float(b))); +} -//--------------------------------------------------------- -// configQuant -//--------------------------------------------------------- +#define DEFAULT_REST_HEIGHT 6 // TODO -void ScoreEdit::configQuant() - { - if (!quantConfig) { - quantConfig = new QuantConfig(_quantStrength, _quantLimit, _quantLen); - connect(quantConfig, SIGNAL(setQuantStrength(int)), SLOT(setQuantStrength(int))); - connect(quantConfig, SIGNAL(setQuantLimit(int)), SLOT(setQuantLimit(int))); - connect(quantConfig, SIGNAL(setQuantLen(bool)), SLOT(setQuantLen(bool))); - } - quantConfig->show(); - } -//--------------------------------------------------------- -// setSteprec -//--------------------------------------------------------- +bool operator< (const note_pos_t& a, const note_pos_t& b) +{ + if (a.height<b.height) return true; + if (a.height>b.height) return false; + return a.vorzeichen<b.vorzeichen; +} -void ScoreEdit::setSteprec(bool flag) - { - canvas->setSteprec(flag); - if (flag == false) - midiin->setChecked(flag); - } -//--------------------------------------------------------- -// eventColorModeChanged -//--------------------------------------------------------- + +int flo_quantize(int tick, int quant_ticks) +{ + //TODO quantizing must be done with the proper functions! + return int(nearbyint((float)tick / quant_ticks))*quant_ticks; +} + +int flo_quantize_floor(int tick, int quant_ticks) +{ + //TODO quantizing must be done with the proper functions, see above + return int(tick / quant_ticks) * quant_ticks; +} -void ScoreEdit::eventColorModeChanged(int mode) - { - colorMode = mode; - colorModeInit = colorMode; - - ((PianoCanvas*)(canvas))->setColorMode(colorMode); - } + +/* builds the event list used by the score editor. + * that list contains only note-on and -off, time-sig- and + * key-change events. + * it stores them sorted by their time (quantized); if more + * events with the same time occur, the NOTE-OFFs are + * put before the NOTE-ONs + * it only operates on parts which were selected in the + * arranger when the score viewer was started + * + * this abstracts the rest of the renderer from muse's internal + * data structures, making this easy to port to another application + */ +void staff_t::create_appropriate_eventlist(const set<Part*>& parts) +{ + using AL::sigmap; + using AL::iSigEvent; + + eventlist.clear(); + + // phase one: fill the list ----------------------------------------- + + //insert note on events + for (set<Part*>::const_iterator part_it=parts.begin(); part_it!=parts.end(); part_it++) + { + Part* part=*part_it; + EventList* el=part->events(); + + for (iEvent it=el->begin(); it!=el->end(); it++) + { + Event& event=it->second; + + if ( (event.isNote() && !event.isNoteOff()) && + ( ((type==GRAND_TOP) && (event.pitch() >= split_note)) || + ((type==GRAND_BOTTOM) && (event.pitch() < split_note)) || + (type==NORMAL) ) ) + { + unsigned begin, end; + begin=flo_quantize(event.tick()+part->tick(), parent->quant_ticks()); + end=flo_quantize(event.endTick()+part->tick(), parent->quant_ticks()); + cout <<"inserting note on at "<<begin<<" with pitch="<<event.pitch()<<" and len="<<end-begin<<endl; + eventlist.insert(pair<unsigned, FloEvent>(begin, FloEvent(begin,event.pitch(), event.velo(),end-begin,FloEvent::NOTE_ON,part,&it->second))); + } + //else ignore it + } + } + + //insert bars and time signatures + for (iSigEvent it=sigmap.begin(); it!=sigmap.end(); it++) + { + unsigned from=it->second->tick; + unsigned to=it->first; + unsigned ticks_per_measure=sigmap.ticksMeasure(it->second->tick); + + if (to > unsigned(SONG_LENGTH)) + { + cout << "time signature's end-of-validness is outside of our song, limiting it." << endl; + to=SONG_LENGTH; + } + + cout << "new signature from tick "<<from<<" to " << to << ": "<<it->second->sig.z<<"/"<<it->second->sig.n<<"; ticks per measure = "<<ticks_per_measure<<endl; + eventlist.insert(pair<unsigned, FloEvent>(from, FloEvent(from, FloEvent::TIME_SIG, it->second->sig.z, it->second->sig.n) ) ); + for (unsigned t=from; t<to; t+=ticks_per_measure) + eventlist.insert(pair<unsigned, FloEvent>(t, FloEvent(t,0,0,ticks_per_measure,FloEvent::BAR) ) ); + } + + //insert key changes + for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++) + eventlist.insert(pair<unsigned, FloEvent>(it->second.tick, FloEvent(it->second.tick,FloEvent::KEY_CHANGE, it->second.key ) ) ); + + + // phase two: deal with overlapping notes --------------------------- + ScoreEventList::iterator it, it2; + + //iterate through all note_on - events + for (it=eventlist.begin(); it!=eventlist.end(); it++) + if (it->second.type==FloEvent::NOTE_ON) + { + unsigned end_tick=it->first + it->second.len; + + //iterate though all (relevant) later note_ons which are + //at the same pitch. if there's a collision, shorten it's len + for (it2=it, it2++; it2!=eventlist.end() && it2->first < end_tick; it2++) + if ((it2->second.type==FloEvent::NOTE_ON) && (it2->second.pitch == it->second.pitch)) + it->second.len=it2->first - it->first; + } + + + // phase three: eliminate zero-length-notes ------------------------- + for (it=eventlist.begin(); it!=eventlist.end();) + if ((it->second.type==FloEvent::NOTE_ON) && (it->second.len<=0)) + eventlist.erase(it++); + else + it++; +} -//--------------------------------------------------------- -// setEventColorMode -//--------------------------------------------------------- -void ScoreEdit::setEventColorMode(int mode) - { - colorMode = mode; - colorModeInit = colorMode; - - ///eventColor->setItemChecked(0, mode == 0); - ///eventColor->setItemChecked(1, mode == 1); - ///eventColor->setItemChecked(2, mode == 2); - evColorBlueAction->setChecked(mode == 0); - evColorPitchAction->setChecked(mode == 1); - evColorVelAction->setChecked(mode == 2); - - ((PianoCanvas*)(canvas))->setColorMode(colorMode); - } +bool is_sharp_key(key_enum t) +{ + return ((t>=KEY_SHARP_BEGIN) && (t<=KEY_SHARP_END)); +} +bool is_b_key(key_enum t) +{ + return ((t>=KEY_B_BEGIN) && (t<=KEY_B_END)); +} -//--------------------------------------------------------- -// clipboardChanged -//--------------------------------------------------------- +int n_accidentials(key_enum t) +{ + if (is_sharp_key(t)) + return t-KEY_SHARP_BEGIN-1; + else + return t-KEY_B_BEGIN-1; +} -void ScoreEdit::clipboardChanged() - { - editPasteAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-eventlist"))); - } -//--------------------------------------------------------- -// selectionChanged -//--------------------------------------------------------- +//note needs to be 0..11 +//always assumes violin clef +//only for internal use +note_pos_t note_pos_(int note, key_enum key) +{ + note_pos_t result; + //C CIS D DIS E F FIS G GIS A AIS H + int foo[12]={0,-1, 1,-1, 2,3,-1, 4,-1, 5, -1,6}; + + if ((note<0) || (note>=12)) + cout << "WARNING: ILLEGAL FUNCTION CALL (note_pos, note out of range)" << endl; + + if (foo[note]!=-1) + { + result.height=foo[note]; + result.vorzeichen=NONE; + } + else + { + if (is_sharp_key(key)) + { + result.height=foo[note-1]; + result.vorzeichen=SHARP; + } + else // if is_b_key + { + result.height=foo[note+1]; + result.vorzeichen=B; + } + } + + // Special cases for GES / FIS keys + if (key==KEY_GES) + { + // convert a H to a Ces + if (note==11) + { + result.height=12; + result.vorzeichen=B; + } + } + else if (key==KEY_FIS) + { + // convert a F to an Eis + if (note==5) + { + result.height=2; + result.vorzeichen=SHARP; + } + } + + return result; +} -void ScoreEdit::selectionChanged() - { - bool flag = canvas->selectionSize() > 0; - editCutAction->setEnabled(flag); - editCopyAction->setEnabled(flag); - editDelEventsAction->setEnabled(flag); - } -//--------------------------------------------------------- -// setSpeaker -//--------------------------------------------------------- +// V -------------------------- <-- height=10 +// I C -------------------------- <-- height=8 +// O L -------------------------- <-- height=6 +// L E -------------------------- <-- height=4 +// I F -------------------------- <-- height=2 +// N --o-- <-- this is C4. height=0 + +// the "spaces" in between the lines have odd numbers. +// that is, the space between line 2 and 4 is numbered 3. + +// these numbers do not change when clef changes. line 2 +// is always the "bottom line" of the system. +// in violin clef, line 2 is E4 +// in bass clef, line 2 is G2 + +note_pos_t note_pos (unsigned note, key_enum key, clef_t clef) +{ + int octave=(note/12)-1; //integer division. note is unsigned + note=note%12; + + //now octave contains the octave the note is in + //(A4 is the 440Hz tone. C4 is the "low C" in the violin clef + //and the "high C" in the bass clef. + //note contains 0 for C, 1 for Cis, ..., 11 for H (or B if you're not german) + + note_pos_t pos=note_pos_(note,key); + + switch (clef) //CLEF_MARKER + { + case VIOLIN: + pos.height=pos.height + (octave-4)*7; + break; + + case BASS: + pos.height=pos.height + (octave-3)*7 + 5; + break; + } + + return pos; +} + + +int calc_len(int l, int d) +{ + // l=0,1,2 -> whole, half, quarter (think of 2^0, 2^1, 2^2) + // d=number of dots + + int tmp=0; + for (int i=0;i<=d;i++) + tmp+=TICKS_PER_WHOLE / (1 << (l+i)); + + return tmp; +} + +bool operator< (const note_len_t& a,const note_len_t& b) //TODO sane sorting order +{ + if (a.len<b.len) return true; + else if (a.dots<b.dots) return true; + else return false; +} + + + +int calc_measure_len(const list<int>& nums, int denom) +{ + int sum=0; + + for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++) + sum+=*it; + + return 64* sum/denom; +} -void ScoreEdit::setSpeaker(bool val) - { - _playEvents = val; - canvas->playEvents(_playEvents); - } +vector<int> create_emphasize_list(const list<int>& nums, int denom) +{ + cout << "creating emphasize list for "; + for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++) + cout << *it << " "; + cout << "/ "<<denom; + + // |----- 8th -----| + int foo[]={4,7,6,7,5,7,6,7}; //if 64 changes, this also must change + int pos=0; + int len=calc_measure_len(nums, denom); + + vector<int> result(len); + + for (int i=0;i<len;i++) + result[i]=foo[i%8]; + + for (list<int>::const_iterator it=nums.begin(); it!=nums.end(); it++) + { + result[pos]=1; + for (int i=1;i<*it;i++) + result[pos + i*64/denom]=2; + pos+= *it * 64 / denom; + } + + result[0]=0; + + for (int i=0;i<len;i++) + { + if (i%8==0) + cout << endl<<i<<":\t"; + cout << result[i]<<" "; + } + cout << endl; + + return result; +} + +vector<int> create_emphasize_list(int num, int denom) +{ + list<int> nums; + + if (num%3 ==0) + { + for (int i=0;i<num/3;i++) + nums.push_back(3); + } + else if (num%2 ==0) + { + for (int i=0;i<num/2;i++) + nums.push_back(2); + } + else // num is odd + { + for (int i=0;i<(num-3)/2;i++) + nums.push_back(2); + + nums.push_back(3); + } + + return create_emphasize_list(nums, denom); +} + +//quant_power2 must be in log(len), that is +//whole, half, quarter, eighth = 0,1,2,3 +//NOT: 1,2,4,8! (think of 2^foo) +//len is in ticks +list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, int quant_power2, bool allow_dots, bool allow_normal) +{ + list<note_len_t> retval; + + if (len_ticks<0) + cout << "WARNING: ILLEGAL FUNCTION CALL in parse_note_len: len_ticks < 0" << endl; + if (begin_tick<0) + cout << "WARNING: ILLEGAL FUNCTION CALL in parse_note_len: begin_tick < 0" << endl; + + if (allow_normal) + { + int dot_max = allow_dots ? quant_power2 : 0; + + for (int i=0;i<=quant_power2;i++) + for (int j=0;j<=dot_max-i;j++) + if (calc_len(i,j) == len_ticks) + { + retval.push_back(note_len_t (i,j)); + return retval; + } + } + + //if !allow_normal or if the above failed + + int begin=begin_tick * 64 / TICKS_PER_WHOLE; + int len=len_ticks * 64 / TICKS_PER_WHOLE; + + unsigned pos=begin; + int len_done=0; + + while (len_done<len) + { + int len_now=0; + int last_number=foo[pos]; + + do {pos++;len_done++;len_now++;} while (! ((foo[pos]<=last_number) || (len_done==len) || (pos==foo.size())) ); + + len_now=len_now*TICKS_PER_WHOLE/64; + + cout << "add " << len_now << " ticks" << endl; + if (allow_dots) + { + for (int i=0;i<=quant_power2;i++) + for (int j=0;j<=quant_power2-i;j++) + if (calc_len(i,j) == len_now) + { + retval.push_back(note_len_t (i,j)); + len_now=0; + } + } + + if (len_now) //the above failed or allow_dots=false + { + for (int i=0; i<=quant_power2; i++) + { + int tmp=calc_len(i,0); + if (tmp <= len_now) + { + retval.push_back(note_len_t(i)); + len_now-=tmp; + if (len_now==0) break; + } + } + } + + if (len_now!=0) + cout << "WARNING: THIS SHOULD NEVER HAPPEN. wasn't able to split note len properly; len_now="<<len_now << endl; + + if (pos==foo.size()) //we cross measure boundaries? + pos=0; + } + + + return retval; +} + + +#define YLEN 10 +#define NOTE_SHIFT 3 + +#define REST_AUSWEICH_X 10 +#define DOT_XDIST 6 +#define DOT_XBEGIN 10 +#define DOT_XBEGIN_REST 10 + +#define NUMBER_HEIGHT (pix_num[0].height()) + +//kann 0 oder 1 sein: +//bei notenkollisionen mit ungerader anzahl von kollidierenden +//wird immer so ausgewichen, dass möglichst wenige ausweichen müssen +//wenn die anzahl aber gerade ist, gibt es keine "bessere" lösung +//in dem fall werden immer die geraden (0) bzw. ungeraden (1) +//ausweichen. +#define AUSWEICHEN_BEVORZUGT 0 + +#define STEM_LEN 30 + +#define DOTTED_RESTS true +#define UNSPLIT_RESTS false + +#define AUX_LINE_LEN 1.5 + +#define ACCIDENTIAL_DIST 11 +#define KEYCHANGE_ACC_DIST 9 +#define KEYCHANGE_ACC_LEFTDIST 9 +#define KEYCHANGE_ACC_RIGHTDIST 0 + + +#define no_notepos note_pos_t() + +#define TIE_DIST 5 +#define TIE_HEIGHT 6 +#define TIE_THICKNESS 3 + +void ScoreCanvas::draw_tie (QPainter& p, int x1, int x4, int yo, bool up, QColor color) +{ + QPainterPath path; + + int y1, y2, y3; + + if (up) + { + y1 = yo - TIE_DIST; + y2 = y1 - TIE_HEIGHT; + y3=y2-TIE_THICKNESS; + } + else + { + y1 = yo + TIE_DIST; + y2 = y1 + TIE_HEIGHT; + y3=y2+TIE_THICKNESS; + } + + int x2 = x1 + (x4-x1)/4; + int x3 = x4 - (x4-x1)/4; + + path.moveTo(x1,y1); + path.cubicTo( x2,y2 , x3,y2 , x4,y1 ); + path.cubicTo( x3,y3 , x2,y3 , x1,y1 ); + + p.setPen(color); + p.setBrush(color); + + p.drawPath(path); +} + +void ScoreCanvas::draw_accidentials(QPainter& p, int x, int y_offset, const list<int>& acc_list, const QPixmap& pix) +{ + int n_acc_drawn=0; + + for (list<int>::const_iterator acc_it=acc_list.begin(); acc_it!=acc_list.end(); acc_it++) + { + int y_coord=2*YLEN - ( *acc_it -2)*YLEN/2; + draw_pixmap(p,x + n_acc_drawn*KEYCHANGE_ACC_DIST,y_offset + y_coord,pix); + n_acc_drawn++; + } +} + +void staff_t::create_itemlist() +{ + key_enum tmp_key=KEY_C; + int lastevent=0; + int next_measure=-1; + int last_measure=-1; + vector<int> emphasize_list=create_emphasize_list(4,4); //actually unneccessary, for safety + + itemlist.clear(); + + for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end(); it++) + { + int t, pitch, len, velo, actual_tick; + FloEvent::typeEnum type; + t=it->first; + pitch=it->second.pitch; + velo=it->second.vel; + len=it->second.len; + type=it->second.type; + actual_tick=it->second.tick; + if (actual_tick==-1) actual_tick=t; + + note_pos_t notepos=note_pos(pitch,tmp_key,clef); + + printf("FLO: t=%i\ttype=%i\tpitch=%i\tvel=%i\tlen=%i\n",it->first, it->second.type, it->second.pitch, it->second.vel, it->second.len); + cout << "\tline="<<notepos.height<<"\tvorzeichen="<<notepos.vorzeichen << endl; + + + if (type==FloEvent::BAR) + { + if (last_measure!=-1) //i.e.: "this is NOT the first bar" + { + if (lastevent==last_measure) //there was no note? + { + unsigned tmppos=(last_measure+t-parent->quant_ticks())/2; + cout << "\tend-of-measure: this was an empty measure. inserting rest in between at t="<<tmppos << endl; + itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,0,0) ); + itemlist[t].insert( FloItem(FloItem::REST_END,notepos,0,0) ); + } + else + { + // if neccessary, insert rest at between last note and end-of-measure + int rest=t-lastevent; + if (rest) + { + printf("\tend-of-measure: set rest at %i with len %i\n",lastevent,rest); + + list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,parent->quant_power2(),DOTTED_RESTS,UNSPLIT_RESTS); + unsigned tmppos=lastevent; + for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++) + { + cout << "\t\tpartial rest with len="<<x->len<<", dots="<<x->dots<<endl; + itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,x->len,x->dots) ); + tmppos+=calc_len(x->len,x->dots); + itemlist[tmppos].insert( FloItem(FloItem::REST_END,notepos,0,0) ); + } + } + } + } + + lastevent=t; + last_measure=t; + next_measure=t+len; + + itemlist[t].insert( FloItem(FloItem::BAR,no_notepos,0,0) ); + } + else if (type==FloEvent::NOTE_ON) + { + int rest=t-lastevent; + if (rest) + { + printf("\tset rest at %i with len %i\n",lastevent,rest); + // no need to check if the rest crosses measure boundaries; + // it can't. + + list<note_len_t> lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,parent->quant_power2(),DOTTED_RESTS,UNSPLIT_RESTS); + unsigned tmppos=lastevent; + for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++) + { + cout << "\t\tpartial rest with len="<<x->len<<", dots="<<x->dots<<endl; + itemlist[tmppos].insert( FloItem(FloItem::REST,notepos,x->len,x->dots) ); + tmppos+=calc_len(x->len,x->dots); + itemlist[tmppos].insert( FloItem(FloItem::REST_END,notepos,0,0) ); + } + } + + + + printf("\tset note at %i with len=%i\n", t, len); + + int tmplen; + bool tied_note; + + // if the note exceeds the current measure, split it. + if (t+len>next_measure) + { + tmplen=next_measure-t; + tied_note=true; + + //append the "remainder" of the note to our EventList, so that + //it gets processed again when entering the new measure + int newlen=len-tmplen; + eventlist.insert(pair<unsigned, FloEvent>(next_measure, FloEvent(actual_tick,pitch, velo,0,FloEvent::NOTE_OFF, it->second.source_part, it->second.source_event))); + eventlist.insert(pair<unsigned, FloEvent>(next_measure, FloEvent(actual_tick,pitch, velo,newlen,FloEvent::NOTE_ON, it->second.source_part, it->second.source_event))); + + cout << "\t\tnote was split to length "<<tmplen<<" + " << newlen<<endl; + } + else + { + tmplen=len; + tied_note=false; + + cout << "\t\tinserting NOTE OFF at "<<t+len<<endl; + eventlist.insert(pair<unsigned, FloEvent>(t+len, FloEvent(t+len,pitch, velo,0,FloEvent::NOTE_OFF,it->second.source_part, it->second.source_event))); + } + + list<note_len_t> lens=parse_note_len(tmplen,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + unsigned tmppos=t; + int n_lens=lens.size(); + int count=0; + for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++) + { + cout << "\t\tpartial note with len="<<x->len<<", dots="<<x->dots<<endl; + count++; + + bool tie; + + if (count<n_lens) + tie=true; // all notes except the last are always tied + else + tie=tied_note; // only the last respects tied_note + + itemlist[tmppos].insert( FloItem(FloItem::NOTE,notepos,x->len,x->dots, tie, actual_tick, it->second.source_part, it->second.source_event) ); + tmppos+=calc_len(x->len,x->dots); + itemlist[tmppos].insert( FloItem(FloItem::NOTE_END,notepos,0,0) ); + } + } + else if (type==FloEvent::NOTE_OFF) + { + lastevent=t; + } + else if (type==FloEvent::TIME_SIG) + { + cout << "inserting TIME SIGNATURE "<<it->second.num<<"/"<<it->second.denom<<" at "<<t<<endl; + itemlist[t].insert( FloItem(FloItem::TIME_SIG, it->second.num, it->second.denom) ); + + emphasize_list=create_emphasize_list(it->second.num, it->second.denom); + } + else if (type==FloEvent::KEY_CHANGE) + { + cout << "inserting KEY CHANGE ("<<it->second.key<<") at "<<t<<endl; + itemlist[t].insert( FloItem(FloItem::KEY_CHANGE, it->second.key) ); + tmp_key=it->second.key; + } + } +} + +void staff_t::process_itemlist() +{ + map<int,int> occupied; + int last_measure=0; + vector<int> emphasize_list=create_emphasize_list(4,4); //unneccessary, only for safety + + //iterate through all times with items + for (ScoreItemList::iterator it2=itemlist.begin(); it2!=itemlist.end(); it2++) + { + set<FloItem, floComp>& curr_items=it2->second; + + cout << "at t="<<it2->first<<endl; + + // phase 0: keep track of active notes, rests ------------------- + // (and occupied lines) and the last measure + // and the current time signature + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + { + if ((it->type==FloItem::NOTE) || (it->type==FloItem::REST)) + occupied[it->pos.height]++; + else if ((it->type==FloItem::NOTE_END) || (it->type==FloItem::REST_END)) + occupied[it->pos.height]--; + else if (it->type==FloItem::BAR) + last_measure=it2->first; + else if (it->type==FloItem::TIME_SIG) + emphasize_list=create_emphasize_list(it->num, it->denom); + } + + cout << "occupied: "; + for (map<int,int>::iterator i=occupied.begin(); i!=occupied.end(); i++) + if (i->second) cout << i->first << "("<<i->second<<") "; + cout << endl; + + + + + + // phase 1: group rests together ----------------------------------- + int n_groups=0; + bool dont_group=false; + + //iterate through all rests R at that time + // iterate through all rests X at that time below R + // if something is between X and R ("barrier"), stop + // else: group them together + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end();) + { + //only operate on rests; ignore rests which are created by this code + //(can be seen on already_grouped) + if ((it->type==FloItem::REST) && (it->already_grouped==false)) + { + cout << "trying to group" << endl; + + int lastheight; + int height_cumulative=0; + int counter=0; + + lastheight=it->pos.height; + + set<FloItem, floComp>::iterator tmp; + for (tmp=it; tmp!=curr_items.end();) + { + cout << "checking if we can proceed with an item at height="<<tmp->pos.height<<endl; + + for (int i=lastheight+1; i<=tmp->pos.height-1; i++) + if (occupied[i]!=0) + { + cout << "we can NOT, because occ["<<i<<"] != 0" << endl; + //stop grouping that rest + goto get_out_here; + } + + lastheight=tmp->pos.height; + + // the current item is a rest with equal len? cool! + if (tmp->type==FloItem::REST && tmp->len==it->len && tmp->dots==it->dots) + { + // füge diese pause zur gruppe dazu und entferne sie von diesem set hier + // entfernen aber nur, wenn sie nicht it, also die erste pause ist, die brauchen wir noch! + cout << "\tgrouping rest at height="<<tmp->pos.height<<endl; + height_cumulative+=tmp->pos.height; + counter++; + if (tmp!=it) + curr_items.erase(tmp++); + else + tmp++; + } + else //it's something else? well, we can stop grouping that rest then + { + cout << "we can NOT, because that item is not a rest" << endl; + //stop grouping that rest + goto get_out_here; + } + } + cout << "no items to proceed on left, continuing" << endl; + get_out_here: + + n_groups++; + + // entferne it vom set und + // füge eine pause mit dem "mittelwert" ein. + // occupied und die "_END"-events bleiben unberührt + + FloItem temp=*it; + temp.already_grouped=true; + + // have we grouped all available rests into one single? + if ( (n_groups==1) && (tmp==curr_items.end()) && !dont_group) + { + cout << "wow, we were able to group all rests into one single" << endl; + if (temp.len==0) //the whole rest is shifted one line (one space and one line) + temp.pos.height=DEFAULT_REST_HEIGHT+2; + else + temp.pos.height=DEFAULT_REST_HEIGHT; + } + else + { + cout << "creating group #"<<n_groups<<endl; + temp.pos.height=nearbyint((float)height_cumulative/counter); + } + + // do NOT first insert, then erase, because if temp.height == + // it->height, the set considers temp and it equal (it doesn't + // take already_grouped into account) + // the result of this: insert does nothing, and erase erases + // the item. effect: you don't have the rest at all + curr_items.erase(it++); + + cout << "replacing all grouped rests with a rest at height="<<temp.pos.height<<endl; + + curr_items.insert(temp); + } + else + { + if (it->type==FloItem::NOTE) + dont_group=true; + + it++; + } + } + + + + + + // phase 2: avoid collisions of items ------------------------------ + set<FloItem, floComp>::iterator lastit, groupbegin, invalid; + invalid=curr_items.end(); + lastit=invalid; + groupbegin=invalid; + int count; + + //TODO FINDMICH MARKER: is "grouping" notes and rests together okay? + // or is it better to ignore rests when grouping? + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + if ( (it->type==FloItem::NOTE) || (it->type==FloItem::REST) ) + { + if (lastit != invalid) + { + if (it->pos.height == lastit->pos.height+1) // they would collide? + { + if (groupbegin==invalid) // we have no group atm? + { + groupbegin=lastit; // start a new group + count=1; // because lastit has to be taken into account. + // for "it", there's a count++ later + } + + // the following will work even on start-new-group, + // because lastit will be "untouched", and that's why + // still be initalized to "false" + it->ausweich=!lastit->ausweich; + + count++; + } + else + { + if (groupbegin!=invalid) //this is the first item which + { //doesn't belong to the previous group any more + if (count%2 == 0) //count is even? + if (modulo(groupbegin->pos.height, 2) == AUSWEICHEN_BEVORZUGT) + for (set<FloItem, floComp>::iterator tmp=groupbegin; tmp!=it; tmp++) + tmp->ausweich=!tmp->ausweich; + + groupbegin=invalid; + } + // else: everything is ok :) + } + } + + lastit=it; + } + + // this could be the case if the last processed item before end() + // still belonged to a group. finalize this last group as well: + if (groupbegin!=invalid) + { + if (count%2 == 0) //count is even? + if (modulo(groupbegin->pos.height, 2) == AUSWEICHEN_BEVORZUGT) + for (set<FloItem, floComp>::iterator tmp=groupbegin; tmp!=curr_items.end(); tmp++) + tmp->ausweich=!tmp->ausweich; + } + // else: everything is ok :) + + + + + + // phase 3: group notes by their length and ------------------------ + // find out appropriate stem directions +group_them_again: + map<int, cumulative_t> lengths; + bool has_whole=false; + + // find out which note lengths are present at that time + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + if (it->type==FloItem::NOTE) + lengths[it->len].add(it->pos.height); + + cout << "note lengths at that time are:"; + for (map<int, cumulative_t>::iterator it=lengths.begin(); it!=lengths.end(); it++) + cout << it->first << "("<< it->second.mean() <<") "; + cout << endl; + + if (lengths.erase(0)) // in case "0" is in the set, erase it + has_whole=true; // but remember there were whole notes + + if (lengths.size()==0) + { + cout << "no notes other than wholes, or no notes at all. we can relax" << endl; + } + else if (lengths.size()==1) + { + pair<const int, cumulative_t>& group=*(lengths.begin()); + stem_t stem; + int shift=0; + cout << "only one non-whole note group (len="<<group.first<<") at height="<<group.second.mean()<< endl; + + if (group.second.mean()>=6) + { + stem=DOWNWARDS; + if (has_whole) + shift=-1; + } + else + { + stem=UPWARDS; + if (has_whole) + shift=1; + } + + // for each note in that group + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + if ( (it->type==FloItem::NOTE) && (it->len==group.first) ) + { + it->stem=stem; + it->shift=shift; + } + } + else if (lengths.size()==2) + { + map<int, cumulative_t>::iterator it=lengths.begin(); + pair<const int, cumulative_t>& group1=*it; + it++; + pair<const int, cumulative_t>& group2=*it; + stem_t stem1, stem2; + int shift1=0, shift2=0; + cout << "two non-whole note group: len="<<group1.first<<" at height="<<group1.second.mean()<<" and len="<<group2.first<<" at height="<<group2.second.mean()<< endl; + + if (group1.second.mean()<group2.second.mean()) + { + stem1=DOWNWARDS; + stem2=UPWARDS; + shift1=-1; + if (has_whole) + shift2=1; + } + else + { + stem1=UPWARDS; + stem2=DOWNWARDS; + shift2=-1; + if (has_whole) + shift1=1; + } + + // for each note in group1 + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + if ( (it->type==FloItem::NOTE) && (it->len==group1.first) ) + { + it->stem=stem1; + it->shift=shift1; + } + + // for each note in group2 + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end(); it++) + if ( (it->type==FloItem::NOTE) && (it->len==group2.first) ) + { + it->stem=stem2; + it->shift=shift2; + } + } + else //more than 2 groups + { + //at this time, there are no iterators pointing to curr_items. + //this means, we can erase and insert safely into curr_items here. + + //group1 contains the longer notes, group2 the shorter + + int group1_n=lengths.size()/2; //round down + int group2_n=lengths.size()-group1_n; + + int group1_len, group2_len; + int group1_len_ticks, group2_len_ticks; + + + map<int, cumulative_t>::iterator lit=lengths.begin(); + for (int i=0;i<group1_n-1;i++) lit++; //go to the group1_n-th entry + group1_len=lit->first; + for (int i=0;i<group2_n;i++) lit++; //go to the (group1_n+group2_n)-th entry (i.e., the last before end() ) + group2_len=lit->first; + + group1_len_ticks=calc_len(group1_len,0); + group2_len_ticks=calc_len(group2_len,0); + + cout << "we have "<<lengths.size()<<" groups. putting the "<<group1_n<<" longest and the "<<group2_n<<"shortest groups together"<<endl; + cout << "\tgroup1 will have len="<<group1_len<<" ("<<group1_len_ticks<<" ticks), group2 will have len="<<group2_len<<" ("<<group2_len_ticks<<" ticks)"<<endl; + + for (set<FloItem, floComp>::iterator it=curr_items.begin(); it!=curr_items.end();) + if (it->type==FloItem::NOTE) + { + //if *it belongs to group1 and has not already its destination length + cout << "\tprocessing note-item with len="<<it->len<<endl; + if (it->len<group1_len) + { + cout << "\t\thas to be changed to fit into group 1" << endl; + FloItem tmp=*it; + curr_items.erase(it++); + + int len_ticks_remaining=calc_len(tmp.len, tmp.dots)-group1_len_ticks; + bool tied_note=tmp.tied; + + + //shorten the current item to it's group's length + tmp.len=group1_len; + tmp.dots=0; + tmp.tied=true; + curr_items.insert(tmp); + + //create items for the remaining lengths (and a note_END for the just created shortened note) + int t=it2->first+group1_len_ticks; + + itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) ); + + list<note_len_t> lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + unsigned tmppos=t; + int n_lens=lens.size(); + int count=0; + for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++) + { + cout << "\t\twhile regrouping: partial note with len="<<x->len<<", dots="<<x->dots<<endl; + count++; + + bool tie; + + if (count<n_lens) + tie=true; // all notes except the last are always tied + else + tie=tied_note; // only the last respects tied_note + + itemlist[tmppos].insert( FloItem(FloItem::NOTE, tmp.pos,x->len,x->dots, tie, tmp.begin_tick, tmp.source_part, tmp.source_event) ); + tmppos+=calc_len(x->len,x->dots); + itemlist[tmppos].insert( FloItem(FloItem::NOTE_END, tmp.pos,0,0) ); + } + + } + //else if *it belongs to group2 and has not already its destination length + else if ((it->len<group2_len) && (it->len>group1_len)) + { + cout << "\t\thas to be changed to fit into group 2" << endl; + + FloItem tmp=*it; + curr_items.erase(it++); + + int len_ticks_remaining=calc_len(tmp.len, tmp.dots)-group2_len_ticks; + bool tied_note=tmp.tied; + + + //shorten the current item to it's group's length + tmp.len=group2_len; + tmp.dots=0; + tmp.tied=true; + curr_items.insert(tmp); + + //create items for the remaining lengths (and a note_END for the just created shortened note) + int t=it2->first+group2_len_ticks; + + itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) ); + + list<note_len_t> lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + unsigned tmppos=t; + int n_lens=lens.size(); + int count=0; + for (list<note_len_t>::iterator x=lens.begin(); x!=lens.end(); x++) + { + cout << "\t\twhile regrouping: partial note with len="<<x->len<<", dots="<<x->dots<<endl; + count++; + + bool tie; + + if (count<n_lens) + tie=true; // all notes except the last are always tied + else + tie=tied_note; // only the last respects tied_note + + itemlist[tmppos].insert( FloItem(FloItem::NOTE,tmp.pos,x->len,x->dots, tie, tmp.begin_tick, tmp.source_part, tmp.source_event) ); + tmppos+=calc_len(x->len,x->dots); + itemlist[tmppos].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) ); + } + + } + else //nothing to do? + { + cout << "\t\tnothing to do" << endl; + it++; + } + } + else + it++; + + goto group_them_again; //do it again + } + + } +} + +//draw a pixmap centered +void ScoreCanvas::draw_pixmap(QPainter& p, int x, int y, const QPixmap& pm) +{ + cout << "drawing pixmap width size="<<pm.width()<<"/"<<pm.height()<<" at "<<x<<"/"<<y<<endl; + p.drawPixmap(x-pm.width()/2,y-pm.height()/2,pm); +} + +QRect bbox_center(int x, int y, const QSize& size) +{ + //why x-foo/2+foo? because due to integer divisions, + // x-foo/2+foo can be smaller than x+foo/2! + return QRect(x-size.width()/2,y-size.height()/2,size.width(),size.height()); +} + +QRect FloItem::bbox() const +{ + return bbox_center(x,y,pix->size()); +} + +void ScoreCanvas::draw_note_lines(QPainter& p, int y) +{ + int xend=width(); + + p.setPen(Qt::black); + + for (int i=0;i<5;i++) + p.drawLine(0,y + i*YLEN - 2*YLEN,xend,y + i*YLEN - 2*YLEN); +} + + +void staff_t::calc_item_pos() +{ + key_enum curr_key=KEY_C; //this has to be KEY_C or KEY_C_B and nothing else, + //because only with these two keys the next (initial) + //key signature is properly drawn. + int pos_add=0; + + for (ScoreItemList::iterator it2=itemlist.begin(); it2!=itemlist.end(); it2++) + { + for (set<FloItem, floComp>::iterator it=it2->second.begin(); it!=it2->second.end();it++) + { + it->x=it2->first * parent->pixels_per_whole()/TICKS_PER_WHOLE +pos_add; + //if this changes, also change the line(s) with YLEN (but not all). don't change it. + it->y=2*YLEN - (it->pos.height-2)*YLEN/2; + + if (it->type==FloItem::NOTE) + { + it->x+=parent->note_x_indent() + it->shift*NOTE_SHIFT; + + switch (it->len) + { + case 0: it->pix=pix_whole; break; + case 1: it->pix=pix_half; break; + default: it->pix=pix_quarter; break; + } + + it->stem_x=it->x; + + if (it->ausweich) + { + if ((it->stem==UPWARDS) || (it->len==0)) + it->x += it->pix->width()-1; //AUSWEICH_X + else + it->x -= it->pix->width()-1; //AUSWEICH_X + } + + //if there's a tie, try to find the tie's destination and set is_tie_dest + if (it->tied) + { + set<FloItem, floComp>::iterator dest; + set<FloItem, floComp>& desttime = itemlist[it2->first+calc_len(it->len,it->dots)]; + for (dest=desttime.begin(); dest!=desttime.end();dest++) + if ((dest->type==FloItem::NOTE) && (dest->pos==it->pos)) + { + dest->is_tie_dest=true; + dest->tie_from_x=it->x; + break; + } + + if (dest==desttime.end()) + cout << "THIS SHOULD NEVER HAPPEN: did not find destination note for tie!" << endl; + } + } + else if (it->type==FloItem::REST) + { + switch (it->len) + { + case 0: it->pix=pix_r1; break; + case 1: it->pix=pix_r2; break; + case 2: it->pix=pix_r4; break; + case 3: it->pix=pix_r8; break; + case 4: it->pix=pix_r16; break; + } + + it->x+=parent->note_x_indent() + (it->ausweich ? REST_AUSWEICH_X : 0); //AUSWEICH_X + } + else if (it->type==FloItem::BAR) + { + //nothing to do :) + } + else if (it->type==FloItem::TIME_SIG) + { + int add=calc_timesig_width(it->num, it->denom); + pos_add+=add; + } + else if (it->type==FloItem::KEY_CHANGE) + { + key_enum new_key=it->key; + + list<int> aufloes_list=calc_accidentials(curr_key, clef, new_key); + list<int> new_acc_list=calc_accidentials(new_key, clef); + + int n_acc_drawn=aufloes_list.size() + new_acc_list.size(); + pos_add+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST; + + curr_key=new_key; + } + } + } +} + +void ScoreCanvas::calc_pos_add_list() +{ + using AL::sigmap; + using AL::iSigEvent; + + + pos_add_list.clear(); + + //process time signatures + for (iSigEvent it=sigmap.begin(); it!=sigmap.end(); it++) + pos_add_list[it->second->tick]+=calc_timesig_width(it->second->sig.z, it->second->sig.n); + + + //process key changes + key_enum curr_key=KEY_C; //this has to be KEY_C or KEY_C_B and nothing else, + //because only with these two keys the next (initial) + //key signature is properly calculated. + for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++) + { + key_enum new_key=it->second.key; + list<int> aufloes_list=calc_accidentials(curr_key, VIOLIN, new_key); //clef argument is unneccessary + list<int> new_acc_list=calc_accidentials(new_key, VIOLIN); //in this case + int n_acc_drawn=aufloes_list.size() + new_acc_list.size(); + pos_add_list[it->second.tick]+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST; + + curr_key=new_key; + } +} + +void ScoreCanvas::draw_items(QPainter& p, int y, staff_t& staff, int x1, int x2) +{ + int from_tick, to_tick; + ScoreItemList::iterator from_it, to_it; + + //drawing too much isn't bad. drawing too few is. + + from_tick=x_to_tick(x1); + from_it=staff.itemlist.lower_bound(from_tick); + //from_it now contains the first time which is fully drawn + //however, the previous beat could still be relevant, when it's + //partly drawn. so we decrement from_it + if (from_it!=staff.itemlist.begin()) from_it--; + + //decrement until we're at a time with a bar + //otherwise, drawing accidentials will be broken + while (from_it!=staff.itemlist.begin() && from_it->second.find(FloItem(FloItem::BAR))==from_it->second.end()) + from_it--; + + + to_tick=x_to_tick(x2); + to_it=staff.itemlist.upper_bound(to_tick); + //to_it now contains the first time which is not drawn at all any more + //however, a tie from 1:04 to 2:01 is stored in 2:01, not in 1:04, + //so for drawing ties, we need to increment to_it, so that the + //"first time not drawn at all any more" is the last which gets + //actually drawn. + if (to_it!=staff.itemlist.end()) to_it++; //do one tick more than neccessary. this will draw ties + + draw_items(p,y, staff, from_it, to_it); +} + +void ScoreCanvas::draw_items(QPainter& p, int y, staff_t& staff) +{ + draw_items(p,y, staff,x_pos,x_pos+width()-x_left); +} + +void ScoreCanvas::draw_items(QPainter& p, int y_offset, staff_t& staff, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it) +{ + // init accidentials properly + vorzeichen_t curr_accidential[7]; + vorzeichen_t default_accidential[7]; + key_enum curr_key; + + curr_key=key_at_tick(from_it->first); + list<int> new_acc_list=calc_accidentials(curr_key, staff.clef); + vorzeichen_t new_accidential = is_sharp_key(curr_key) ? SHARP : B; + + for (int i=0;i<7;i++) + curr_accidential[i]=default_accidential[i]=NONE; + + for (list<int>::iterator acc_it=new_acc_list.begin(); acc_it!=new_acc_list.end(); acc_it++) + default_accidential[*acc_it % 7]=curr_accidential[*acc_it % 7]=new_accidential; + + + + for (ScoreItemList::iterator it2=from_it; it2!=to_it; it2++) + { + cout << "at t="<<it2->first << endl; + + int upstem_y1 = -1, upstem_y2=-1, upstem_x=-1, upflag=-1; + int downstem_y1 = -1, downstem_y2=-1, downstem_x=-1, downflag=-1; + + for (set<FloItem, floComp>::iterator it=it2->second.begin(); it!=it2->second.end();it++) + { + if (it->type==FloItem::NOTE) + { + cout << "\tNOTE at line"<<it->pos.height<<" with acc.="<<it->pos.vorzeichen<<", len="<<pow(2,it->len); + for (int i=0;i<it->dots;i++) cout << "."; + cout << " , stem="; + if (it->stem==UPWARDS) + cout << "UPWARDS"; + else + cout << "DOWNWARDS"; + + cout << " , shift="<<it->shift<<", ausweich="<<it->ausweich<<", "; + if (!it->tied) cout << "un"; + cout << "tied, is_tie_dest="<<it->is_tie_dest<<endl; + + if (it->len!=0) //only for non-whole notes the stems are relevant! + { + if (it->stem==UPWARDS) + { + if (upstem_y1 == -1) + upstem_y1=it->y; + + upstem_y2=it->y; + + + if ((upflag!=-1) && (upflag!=it->len)) + cout << "WARNING: THIS SHOULD NEVER HAPPEN: upflag != this->flag" << endl; + upflag=it->len; + + if ((upstem_x!=-1) && (upstem_x!=it->stem_x )) + cout << "WARNING: THIS SHOULD NEVER HAPPEN: upstem_x != x_result" << endl; + upstem_x=it->stem_x; + } + else + { + if (downstem_y1 == -1) + downstem_y1=it->y; + + downstem_y2=it->y; + + + if ((downflag!=-1) && (downflag!=it->len)) + cout << "WARNING: THIS SHOULD NEVER HAPPEN: downflag != this->flag" << endl; + downflag=it->len; + + if ((downstem_x!=-1) && (downstem_x!=it->stem_x)) + cout << "WARNING: THIS SHOULD NEVER HAPPEN: downstem_x != x_result" << endl; + downstem_x=it->stem_x; //important: before the below calculation! + } + } + + + if (it->pos.height <= 0) //we need auxiliary lines on the bottom? + { + p.setPen(Qt::black); + for (int i=0; i>=it->pos.height; i-=2) + p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,y_offset + 2*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,y_offset + 2*YLEN - (i-2)*YLEN/2); + } + else if (it->pos.height >= 12) //we need auxiliary lines on the top? + { + p.setPen(Qt::black); + for (int i=12; i<=it->pos.height; i+=2) + p.drawLine(it->x-it->pix->width()*AUX_LINE_LEN/2 -x_pos+x_left,y_offset + 2*YLEN - (i-2)*YLEN/2,it->x+it->pix->width()*AUX_LINE_LEN/2-x_pos+x_left,y_offset + 2*YLEN - (i-2)*YLEN/2); + } + + it->is_active= ( (song->cpos() >= it->source_event->tick() + it->source_part->tick()) && + (song->cpos() < it->source_event->endTick() + it->source_part->tick()) ); + + + int color_index; + switch (coloring_mode) + { + case COLOR_MODE_BLACK: + color_index=BLACK_PIXMAP; + break; + + case COLOR_MODE_PART: + color_index=it->source_part->colorIndex(); + break; + + case COLOR_MODE_PITCH: //TODO + break; + } + if (audio->isPlaying() && it->is_active) + color_index=HIGHLIGHTED_PIXMAP; + + + draw_pixmap(p,it->x -x_pos+x_left,y_offset + it->y,it->pix[color_index]); + //TODO FINDMICH maybe draw a margin around bright colors? + //maybe draw the default color in black? + + //draw dots + + int x_dot=DOT_XBEGIN; + int y_dot; + if (modulo(it->pos.height, 2) == 0) //note is on a line? + y_dot=YLEN * 0.33; // actually 0.5, but that would be _exactly_ in the space + else //note is between two lines? + y_dot=YLEN * 0.1; + + if (it->stem==DOWNWARDS) + y_dot=-y_dot; + //else y_dot=y_dot; + + for (int i=0;i<it->dots;i++) + { + draw_pixmap(p,it->x+x_dot -x_pos+x_left,y_offset + it->y+y_dot,pix_dot[color_index]); + x_dot+=DOT_XDIST; + } + + + + //draw accidentials + if (it->pos.vorzeichen != curr_accidential[modulo(it->pos.height,7)]) + { + QPixmap* acc_pix; + switch (it->pos.vorzeichen) + { + case NONE: acc_pix=pix_noacc; break; + case SHARP: acc_pix=pix_sharp; break; + case B: acc_pix=pix_b; break; + } + draw_pixmap(p,it->x-ACCIDENTIAL_DIST -x_pos+x_left,y_offset + it->y, acc_pix[color_index]); + + curr_accidential[modulo(it->pos.height,7)]=it->pos.vorzeichen; + } + + + //if needed, draw tie + if (it->is_tie_dest) + { + cout << "drawing tie" << endl; + draw_tie(p,it->tie_from_x-x_pos+x_left,it->x -x_pos+x_left,y_offset + it->y, (it->len==0) ? true : (it->stem==DOWNWARDS) , config.partColors[color_index]); + // in english: "if it's a whole note, tie is upwards (true). if not, tie is upwards if + // stem is downwards and vice versa" + } + } + else if (it->type==FloItem::REST) + { + cout << "\tREST at line"<<it->pos.height<<" with len="<<pow(2,it->len); + for (int i=0;i<it->dots;i++) cout << "."; + cout << " , ausweich="<<it->ausweich<<endl; + + draw_pixmap(p,it->x -x_pos+x_left,y_offset + it->y,*it->pix); + + + //draw dots + + int x_dot=DOT_XBEGIN_REST; + int y_dot; + if (modulo(it->pos.height, 2) == 0) //rest is on a line? + y_dot=YLEN * 0.33; // actually 0.5, but that would be _exactly_ in the space + else //note is between two lines? + y_dot=YLEN * 0.1; + + if (it->len!=0) // all rests except the whole are treated as + y_dot=-y_dot; // if they had a downwards stem + + for (int i=0;i<it->dots;i++) + { + draw_pixmap(p,it->x+x_dot -x_pos+x_left,y_offset + it->y+y_dot,pix_dot[BLACK_PIXMAP]); + x_dot+=DOT_XDIST; + } + } + else if (it->type==FloItem::BAR) + { + cout << "\tBAR" << endl; + + p.setPen(Qt::black); + p.drawLine(it->x -x_pos+x_left,y_offset -2*YLEN,it->x -x_pos+x_left,y_offset +2*YLEN); + + for (int i=0;i<7;i++) + curr_accidential[i]=default_accidential[i]; + } + else if (it->type==FloItem::TIME_SIG) + { + cout << "\tTIME SIGNATURE: "<<it->num<<"/"<<it->denom<<endl; + + draw_timesig(p, it->x - x_pos+x_left, y_offset, it->num, it->denom); + } + else if (it->type==FloItem::KEY_CHANGE) + { + key_enum new_key=it->key; + cout << "\tKEY CHANGE: from "<<curr_key<<" to "<<new_key<<endl; + + list<int> aufloes_list=calc_accidentials(curr_key, staff.clef, new_key); + list<int> new_acc_list=calc_accidentials(new_key, staff.clef); + + // vorzeichen aus curr_key auflösen + draw_accidentials(p, it->x + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, y_offset, aufloes_list, pix_noacc[BLACK_PIXMAP]); + + // alle vorzeichen aus new_key zeichnen + QPixmap* pix = is_sharp_key(new_key) ? &pix_sharp[BLACK_PIXMAP] : &pix_b[BLACK_PIXMAP]; + vorzeichen_t new_accidential = is_sharp_key(new_key) ? SHARP : B; + + draw_accidentials(p, it->x + aufloes_list.size()*KEYCHANGE_ACC_DIST + KEYCHANGE_ACC_LEFTDIST - x_pos+x_left, y_offset, new_acc_list, *pix); + + for (int i=0;i<7;i++) + curr_accidential[i]=default_accidential[i]=NONE; + + for (list<int>::iterator acc_it=new_acc_list.begin(); acc_it!=new_acc_list.end(); acc_it++) + default_accidential[*acc_it % 7]=curr_accidential[*acc_it % 7]=new_accidential; + + curr_key=new_key; + } + } + + p.setPen(Qt::black); + //note: y1 is bottom, y2 is top! + if (upstem_x!=-1) + { + upstem_x=upstem_x-pix_quarter[0].width()/2 +pix_quarter[0].width() -1; + p.drawLine(upstem_x -x_pos+x_left, y_offset + upstem_y1, upstem_x -x_pos+x_left, y_offset + upstem_y2-STEM_LEN); + + if (upflag>=3) //if the note needs a flag + p.drawPixmap(upstem_x -x_pos+x_left,y_offset + upstem_y2-STEM_LEN,pix_flag_up[upflag-3]); + } + if (downstem_x!=-1) + { + downstem_x=downstem_x-pix_quarter[0].width()/2; + p.drawLine(downstem_x -x_pos+x_left, y_offset + downstem_y1+STEM_LEN, downstem_x -x_pos+x_left, y_offset + downstem_y2); + + if (downflag>=3) //if the note needs a flag + p.drawPixmap(downstem_x -x_pos+x_left,y_offset + downstem_y1+STEM_LEN-pix_flag_down[downflag-3].height(),pix_flag_down[downflag-3]); + } + } +} + +bool ScoreCanvas::need_redraw_for_hilighting() +{ + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + if (need_redraw_for_hilighting(it->itemlist)) return true; + + return false; +} + +bool ScoreCanvas::need_redraw_for_hilighting(ScoreItemList& itemlist) +{ + return need_redraw_for_hilighting(itemlist, x_pos,x_pos+width()-x_left); +} + +bool ScoreCanvas::need_redraw_for_hilighting(ScoreItemList& itemlist, int x1, int x2) +{ + int from_tick, to_tick; + ScoreItemList::iterator from_it, to_it; + + from_tick=x_to_tick(x1); + from_it=itemlist.lower_bound(from_tick); + //from_it now contains the first time which is fully drawn + //however, the previous beat could still be relevant, when it's + //partly drawn. so we decrement from_it + if (from_it!=itemlist.begin()) from_it--; + + to_tick=x_to_tick(x2); + to_it=itemlist.upper_bound(to_tick); + //to_it now contains the first time which is not drawn at all any more + + return need_redraw_for_hilighting(from_it, to_it); +} + +bool ScoreCanvas::need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it) +{ + //if we aren't playing, there will never be a need for redrawing due to highlighting things + if (audio->isPlaying()==false) + return false; + + for (ScoreItemList::iterator it2=from_it; it2!=to_it; it2++) + for (set<FloItem, floComp>::iterator it=it2->second.begin(); it!=it2->second.end();it++) + if (it->type==FloItem::NOTE) + { + bool is_active= ( (song->cpos() >= it->source_event->tick() + it->source_part->tick()) && + (song->cpos() < it->source_event->endTick() + it->source_part->tick()) ); + if (it->is_active != is_active) + return true; + } + + return false; +} + +int clef_height(clef_t clef) +{ + switch (clef) //CLEF_MARKER + { + case VIOLIN: return 4; + case BASS: return 8; + default: + cout << "WARNING: ILLEGAL FUNCTION CALL in clef_height()" << endl; + return 6; + } +} + +#define TIMESIG_LEFTMARGIN 5 +#define TIMESIG_RIGHTMARGIN 5 +#define DIGIT_YDIST 9 +#define DIGIT_WIDTH 12 + +#define CLEF_LEFTMARGIN 5 +#define CLEF_RIGHTMARGIN 5 + +void ScoreCanvas::draw_preamble(QPainter& p, int y_offset, clef_t clef) +{ + int x_left_old=x_left; + int tick=x_to_tick(x_pos); + + // draw clef -------------------------------------------------------- + QPixmap* pix_clef= (clef==BASS) ? pix_clef_bass : pix_clef_violin; + int y_coord=2*YLEN - ( clef_height(clef) -2)*YLEN/2; + + draw_pixmap(p,CLEF_LEFTMARGIN + pix_clef->width()/2,y_offset + y_coord,*pix_clef); + + x_left= CLEF_LEFTMARGIN + pix_clef->width() + CLEF_RIGHTMARGIN; + + + // draw accidentials ------------------------------------------------ + if (preamble_contains_keysig) + { + x_left+=KEYCHANGE_ACC_LEFTDIST; + + key_enum key=key_at_tick(tick); + QPixmap* pix_acc=is_sharp_key(key) ? &pix_sharp[BLACK_PIXMAP] : &pix_b[BLACK_PIXMAP]; + list<int> acclist=calc_accidentials(key,clef); + + draw_accidentials(p,x_left, y_offset, acclist ,*pix_acc); + + x_left+=acclist.size()*KEYCHANGE_ACC_DIST + KEYCHANGE_ACC_RIGHTDIST; + } + + + // draw time signature ---------------------------------------------- + if (preamble_contains_timesig) + { + x_left+=TIMESIG_LEFTMARGIN; + + timesig_t timesig=timesig_at_tick(tick); + + draw_timesig(p, x_left, y_offset, timesig.num, timesig.denom); + + x_left+=calc_timesig_width(timesig.num, timesig.denom)+TIMESIG_RIGHTMARGIN; + } + + // draw bar --------------------------------------------------------- + p.setPen(Qt::black); + p.drawLine(x_left,y_offset -2*YLEN,x_left,y_offset +2*YLEN); + + + if (x_left_old!=x_left) + emit viewport_width_changed(viewport_width()); +} + + +void ScoreCanvas::draw_timesig(QPainter& p, int x, int y_offset, int num, int denom) +{ + int num_width=calc_number_width(num); + int denom_width=calc_number_width(denom); + int width=((num_width > denom_width) ? num_width : denom_width); + int num_indent=(width-num_width)/2 + TIMESIG_LEFTMARGIN; + int denom_indent=(width-denom_width)/2 + TIMESIG_LEFTMARGIN; + + draw_number(p, x+num_indent, y_offset -DIGIT_YDIST, num); + draw_number(p, x+denom_indent, y_offset +DIGIT_YDIST, denom); +} + +int calc_timesig_width(int num, int denom) +{ + int num_width=calc_number_width(num); + int denom_width=calc_number_width(denom); + int width=((num_width > denom_width) ? num_width : denom_width); + return width+TIMESIG_LEFTMARGIN+TIMESIG_RIGHTMARGIN; +} + +int calc_number_width(int n) +{ + string str=IntToStr(n); + return (str.length()*DIGIT_WIDTH); +} + +void ScoreCanvas::draw_number(QPainter& p, int x, int y, int n) +{ + string str=IntToStr(n); + int curr_x=x+DIGIT_WIDTH/2; + + for (size_t i=0;i<str.length(); i++) + { + draw_pixmap(p, curr_x, y, pix_num[str[i]-'0']); + curr_x+=DIGIT_WIDTH; + } +} + + +void ScoreCanvas::draw(QPainter& p, const QRect&) +{ + cout <<"now in ScoreCanvas::draw"<<endl; + + + + p.setPen(Qt::black); + + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + { + //TODO: maybe only draw visible staves? + draw_note_lines(p,it->y_draw - y_pos); + draw_preamble(p,it->y_draw - y_pos, it->clef); + p.setClipRect(x_left+1,0,p.device()->width(),p.device()->height()); + draw_items(p,it->y_draw - y_pos, *it); + p.setClipping(false); + } +} + + +list<int> calc_accidentials(key_enum key, clef_t clef, key_enum next_key) +{ + list<int> result; + + int violin_sharp_pos[]={10,7,11,8,5,9,6}; //CLEF_MARKER + int violin_b_pos[]={6,9,5,8,4,7,3}; + int bass_sharp_pos[]={8,5,9,6,3,7,4}; + int bass_b_pos[]={4,7,3,6,2,5,1}; + + int* accidential_pos; + + switch (clef) + { + case VIOLIN: accidential_pos = is_sharp_key(key) ? violin_sharp_pos : violin_b_pos; break; + case BASS: accidential_pos = is_sharp_key(key) ? bass_sharp_pos : bass_b_pos; break; + } + + int begin=0; + + if (is_sharp_key(key)==is_sharp_key(next_key)) //same kind of key (both b or both #)? + begin=n_accidentials(next_key); + else + begin=0; + + + int end=n_accidentials(key); + + for (int i=begin; i<end; i++) + result.push_back(accidential_pos[i]); + + return result; +} + + + + +int ScoreCanvas::tick_to_x(int t) +{ + int x=t*pixels_per_whole()/TICKS_PER_WHOLE; + + for (std::map<int,int>::iterator it=pos_add_list.begin(); it!=pos_add_list.end() && it->first<=t; it++) + x+=it->second; + + return x; +} + +int ScoreCanvas::calc_posadd(int t) +{ + int result=0; + + for (std::map<int,int>::iterator it=pos_add_list.begin(); it!=pos_add_list.end() && it->first<t; it++) + result+=it->second; + + return result; +} + +//doesn't round mathematically correct, but i don't think this +//will be a problem, because a tick is pretty small +int ScoreCanvas::x_to_tick(int x) +{ + int t=TICKS_PER_WHOLE * x/pixels_per_whole(); + int min_t=0; + + cout << "t="<<t<<endl; + + for (std::map<int,int>::iterator it=pos_add_list.begin(); it!=pos_add_list.end() && it->first<t; it++) + { + cout << "at pos_add event at t="<<it->first<<", add="<<it->second<<endl; + min_t=it->first; + x-=it->second; + t=TICKS_PER_WHOLE * x/pixels_per_whole(); + } + + return t > min_t ? t : min_t; +} + +key_enum ScoreCanvas::key_at_tick(int t_) +{ + unsigned int t= (t_>=0) ? t_ : 0; + + return keymap.keyAtTick(t); +} + +timesig_t ScoreCanvas::timesig_at_tick(int t_) +{ + timesig_t tmp; + unsigned int t= (t_>=0) ? t_ : 0; + + AL::sigmap.timesig(t, tmp.num, tmp.denom); + + return tmp; +} + +int ScoreCanvas::height_to_pitch(int h, clef_t clef) +{ + int foo[]={0,2,4,5,7,9,11}; + + switch(clef) //CLEF_MARKER + { + case VIOLIN: return foo[modulo(h,7)] + ( divide_floor(h,7)*12 ) + 60; + case BASS: return foo[modulo((h-5),7)] + ( divide_floor(h-5,7)*12 ) + 48; + default: + cout << "WARNING: THIS SHOULD NEVER HAPPEN: unknown clef in height_to_pitch" << endl; + return 60; + } +} + +int ScoreCanvas::height_to_pitch(int h, clef_t clef, key_enum key) +{ + int add=0; + + list<int> accs=calc_accidentials(key,clef); + + for (list<int>::iterator it=accs.begin(); it!=accs.end(); it++) + { + if (modulo(*it,7) == modulo(h,7)) + { + add=is_sharp_key(key) ? 1 : -1; + break; + } + } + + return height_to_pitch(h,clef)+add; +} + +int ScoreCanvas::y_to_height(int y) +{ + return int(nearbyint(float(2*YLEN - y)*2.0/YLEN))+2 ; +} + +int ScoreCanvas::y_to_pitch(int y, int t, clef_t clef) +{ + return height_to_pitch(y_to_height(y), clef, key_at_tick(t)); +} + + +#define DRAG_INIT_DISTANCE 5 + +void ScoreCanvas::mousePressEvent (QMouseEvent* event) +{ + // den errechneten tick immer ABrunden! + // denn der "bereich" eines schlags geht von schlag_begin bis nächsterschlag_begin-1 + // noten werden aber genau in die mitte dieses bereiches gezeichnet + + list<staff_t>::iterator staff_it=staff_at_y(event->y() + y_pos); + + int y=event->y() + y_pos - staff_it->y_draw; + int x=event->x()+x_pos-x_left; + int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); + //TODO quantizing must (maybe?) be done with the proper functions + + if (staff_it!=staves.end()) + { + if (event->x() <= x_left) //clicked in the preamble? + { + if (event->button() == Qt::RightButton) //right-click? + { + current_staff=staff_it; + staff_menu->popup(event->globalPos()); + } + else if (event->button() == Qt::MidButton) //middle click? + { + remove_staff(staff_it); + } + else if (event->button() == Qt::LeftButton) //left click? + { + current_staff=staff_it; + dragging_staff=true; + } + } + else + { + ScoreItemList& itemlist=staff_it->itemlist; + + cout << "mousePressEvent at "<<x<<"/"<<y<<"; tick="<<tick<<endl; + set<FloItem, floComp>::iterator set_it; + for (set_it=itemlist[tick].begin(); set_it!=itemlist[tick].end(); set_it++) + if (set_it->type==FloItem::NOTE) + if (set_it->bbox().contains(x,y)) + break; + + if (set_it!=itemlist[tick].end()) //we found something? + { + mouse_down_pos=event->pos(); + mouse_operation=NO_OP; + + int t=tick; + set<FloItem, floComp>::iterator found; + + do + { + found=itemlist[t].find(FloItem(FloItem::NOTE, set_it->pos)); + if (found == itemlist[t].end()) + { + cout << "FATAL: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl; + break; + } + else + { + t+=calc_len(found->len, found->dots); + } + } while (found->tied); + + int total_begin=set_it->begin_tick; + int total_end=t; + + int this_begin=tick; + int this_end=this_begin+calc_len(set_it->len, set_it->dots); + + //that's the only note corresponding to the event? + if (this_begin==total_begin && this_end==total_end) + { + if (x < set_it->x) + mouse_x_drag_operation=BEGIN; + else + mouse_x_drag_operation=LENGTH; + } + //that's NOT the only note? + else + { + if (this_begin==total_begin) + mouse_x_drag_operation=BEGIN; + else if (this_end==total_end) + mouse_x_drag_operation=LENGTH; + else + mouse_x_drag_operation=NO_OP; + } + + cout << "you clicked at a note with begin at "<<set_it->begin_tick<<" and end at "<<t<<endl; + cout << "x-drag-operation will be "<<mouse_x_drag_operation<<endl; + cout << "pointer to part is "<<set_it->source_part; + if (!set_it->source_part) cout << " (WARNING! THIS SHOULD NEVER HAPPEN!)"; + cout << endl; + + dragged_event=*set_it->source_event; + dragged_event_part=set_it->source_part; + dragged_event_original_pitch=dragged_event.pitch(); + + if ((mouse_erases_notes) || (event->button()==Qt::MidButton)) //erase? + { + audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); + } + else if (event->button()==Qt::LeftButton) //edit? + { + setMouseTracking(true); + dragging=true; + song->startUndo(); + } + } + else //we found nothing? + { + if ((event->button()==Qt::LeftButton) && (mouse_inserts_notes)) + { + signed int relative_tick=(signed) tick - curr_part->tick(); + if (relative_tick>=0) //TODO FINDMICH do that better + { + song->startUndo(); + //stopping undo at the end of this function is unneccessary + //because we'll begin a drag right after it. finishing + //this drag will stop undo as well (in mouseReleaseEvent) + + Event newevent(Note); + newevent.setPitch(y_to_pitch(y,tick, staff_it->clef)); + newevent.setVelo(64); //TODO + newevent.setVeloOff(64); //TODO + newevent.setTick(relative_tick); + newevent.setLenTick((new_len>0)?new_len:last_len); + + audio->msgAddEvent(newevent, curr_part, false, false, false); + + dragged_event_part=curr_part; + dragged_event=newevent; + dragged_event_original_pitch=newevent.pitch(); + + mouse_down_pos=event->pos(); + mouse_operation=NO_OP; + mouse_x_drag_operation=LENGTH; + + song_changed(SC_EVENT_INSERTED); + + setMouseTracking(true); + dragging=true; + //song->startUndo(); unneccessary because we have started it already above + } + } + } + } + } +} + +void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) +{ + if (dragging) + { + if (event->button()==Qt::LeftButton) + { + if (mouse_operation==LENGTH) + { + if (flo_quantize(dragged_event.lenTick(), quant_ticks()) <= 0) + { + cout << "new length <= 0, erasing item" << endl; + audio->msgDeleteEvent(dragged_event, dragged_event_part, false, false, false); + } + else + { + last_len=flo_quantize(dragged_event.lenTick(), quant_ticks()); + } + } + + song->endUndo(SC_EVENT_MODIFIED); + setMouseTracking(false); + dragging=false; + + x_scroll_speed=0; x_scroll_pos=0; + } + } + + if (dragging_staff) + { + merge_staves(staff_at_y(event->y()+y_pos), current_staff); + dragging_staff=false; + + y_scroll_speed=0; y_scroll_pos=0; + } +} + +#define PITCH_DELTA 5 + + +void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) +{ + if (dragging) + { + int dx=event->x()-mouse_down_pos.x(); + int dy=event->y()-mouse_down_pos.y(); + + int x=event->x()+x_pos-x_left; + + int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); + + if (mouse_operation==NO_OP) + { + if ((abs(dx)>DRAG_INIT_DISTANCE) && (mouse_x_drag_operation!=NO_OP)) + { + cout << "mouse-operation is now "<<mouse_x_drag_operation<<endl; + mouse_operation=mouse_x_drag_operation; + } + else if (abs(dy)>DRAG_INIT_DISTANCE) + { + cout << "mouse-operation is now PITCH" << endl; + mouse_operation=PITCH; + } + } + + int new_pitch; + + switch (mouse_operation) + { + case NONE: + break; + + case PITCH: + cout << "changing pitch, delta="<<nearbyint((float)dy/PITCH_DELTA)<<endl; + new_pitch=dragged_event_original_pitch - nearbyint((float)dy/PITCH_DELTA); + + if (dragged_event.pitch()!=new_pitch) + { + Event tmp=dragged_event.clone(); + tmp.setPitch(new_pitch); + + audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); + dragged_event=tmp; + + song_changed(SC_EVENT_INSERTED); + } + + break; + + case BEGIN: + if (dragged_event.tick()+dragged_event_part->tick() != unsigned(tick)) //TODO FINDMICHJETZT tick kann unsigned werden + { + Event tmp=dragged_event.clone(); + + if (tick-signed(dragged_event_part->tick()) >= 0) //TODO FINDMICH do that better + tmp.setTick(tick-dragged_event_part->tick()); + + audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); + dragged_event=tmp; + + song_changed(SC_EVENT_INSERTED); + } + + break; + + case LENGTH: + tick+=quant_ticks(); + if (dragged_event.tick()+dragged_event.lenTick() + dragged_event_part->tick() != unsigned(tick)) + { + Event tmp=dragged_event.clone(); + + if (tick-signed(dragged_event.tick() -dragged_event_part->tick()) >= 0) //TODO FINDMICH do that better + tmp.setLenTick(tick-dragged_event.tick() -dragged_event_part->tick()); + + audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); + dragged_event=tmp; + + song_changed(SC_EVENT_INSERTED); + } + + break; + } + + + if ((mouse_operation==LENGTH) || (mouse_operation==BEGIN)) //x-scrolling enabled? + { + int win_x=event->x(); + + if (win_x < x_left + SCROLL_MARGIN) + { + x_scroll_speed=(win_x - (x_left + SCROLL_MARGIN)) * SCROLL_SPEED; + if (x_scroll_speed < -SCROLL_SPEED_MAX) x_scroll_speed=-SCROLL_SPEED_MAX; + } + else if (win_x > width() - SCROLL_MARGIN) + { + x_scroll_speed=(win_x - (width() - SCROLL_MARGIN)) * SCROLL_SPEED; + if (x_scroll_speed > SCROLL_SPEED_MAX) x_scroll_speed=SCROLL_SPEED_MAX; + } + else + x_scroll_speed=0; + } + else + { + x_scroll_speed=0; + } + } + + if (dragging_staff) //y-scrolling enabled? + { + int win_y=event->y(); + + if (win_y < SCROLL_MARGIN) + { + y_scroll_speed=(win_y - SCROLL_MARGIN) * SCROLL_SPEED; + if (y_scroll_speed < -SCROLL_SPEED_MAX) y_scroll_speed=-SCROLL_SPEED_MAX; + } + else if (win_y > height() - SCROLL_MARGIN) + { + y_scroll_speed=(win_y - (height() - SCROLL_MARGIN)) * SCROLL_SPEED; + if (y_scroll_speed > SCROLL_SPEED_MAX) y_scroll_speed=SCROLL_SPEED_MAX; + } + else + y_scroll_speed=0; + } + else + { + y_scroll_speed=0; + } +} + +void ScoreCanvas::heartbeat_timer_event() +{ + if (x_scroll_speed) + { + int old_xpos=x_pos; + + x_scroll_pos+=x_scroll_speed*heartBeatTimer->interval()/1000.0; + int tmp=int(x_scroll_pos); + if (tmp!=0) + x_pos+=tmp; + x_scroll_pos-=tmp; + + if (x_pos<0) x_pos=0; + if (x_pos>canvas_width()) x_pos=canvas_width(); + + if (old_xpos!=x_pos) emit xscroll_changed(x_pos); + } + + if (y_scroll_speed) + { + int old_ypos=y_pos; + + y_scroll_pos+=y_scroll_speed*heartBeatTimer->interval()/1000.0; + int tmp=int(y_scroll_pos); + if (tmp!=0) + y_pos+=tmp; + y_scroll_pos-=tmp; + + if (y_pos<0) y_pos=0; + if (y_pos>canvas_height()) y_pos=canvas_height(); + + if (old_ypos!=y_pos) emit yscroll_changed(y_pos); + } +} + +void ScoreCanvas::x_scroll_event(int x) +{ + cout << "SCROLL EVENT: x="<<x<<endl; + x_pos=x; + redraw(); +} + +void ScoreCanvas::y_scroll_event(int y) +{ + cout << "SCROLL EVENT: y="<<y<<endl; + y_pos=y; + redraw(); +} + + +//if force is true, it will always happen something +//if force is false, it will only happen something, if +//tick isn't visible at all. if it's visible, but not at +//the position goto would set it to, nothing happens +void ScoreCanvas::goto_tick(int tick, bool force) +{ + if (!force) + { + if (tick < x_to_tick(x_pos)) + { + x_pos=tick_to_x(tick) - x_left; + if (x_pos<0) x_pos=0; + if (x_pos>canvas_width()) x_pos=canvas_width(); + + emit xscroll_changed(x_pos); + } + else if (tick > x_to_tick(x_pos+viewport_width()*PAGESTEP)) + { + x_pos=tick_to_x(tick); + if (x_pos<0) x_pos=0; + if (x_pos>canvas_width()) x_pos=canvas_width(); + + emit xscroll_changed(x_pos); + } + } + else + { + x_pos=tick_to_x(tick)-viewport_width()/2; + if (x_pos<0) x_pos=0; + if (x_pos>canvas_width()) x_pos=canvas_width(); + + emit xscroll_changed(x_pos); + } +} //--------------------------------------------------------- // resizeEvent //--------------------------------------------------------- -void ScoreEdit::resizeEvent(QResizeEvent* ev) - { - QWidget::resizeEvent(ev); - _widthInit = ev->size().width(); - _heightInit = ev->size().height(); - } +void ScoreCanvas::resizeEvent(QResizeEvent* ev) +{ + QWidget::resizeEvent(ev); //TODO is this really neccessary? + emit viewport_width_changed( viewport_width() ); + emit viewport_height_changed( viewport_height() ); +} -/* -//--------------------------------------------------------- -// trackInfoScroll -//--------------------------------------------------------- +void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll) +{ + if (index==0) + { + if (scroll) //potential need to scroll? + { + switch (song->follow()) + { + case Song::NO: break; + case Song::JUMP: goto_tick(tick,false); break; + case Song::CONTINUOUS: goto_tick(tick,true); break; + } + } + + if (need_redraw_for_hilighting()) + redraw(); + } +} -void ScoreEdit::trackInfoScroll(int y) - { - if (trackInfo->visibleWidget()) - trackInfo->visibleWidget()->move(0, -y); - } -*/ -//--------------------------------------------------------- -// initShortcuts -//--------------------------------------------------------- +void ScoreCanvas::recalc_staff_pos() +{ + int y=0; + + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + { + it->y_top=y; + switch (it->type) + { + case NORMAL: + it->y_draw = it->y_top + STAFF_DISTANCE/2; + it->y_bottom = it->y_draw + STAFF_DISTANCE/2; + break; + case GRAND_TOP: + it->y_draw = it->y_top + STAFF_DISTANCE/2; + it->y_bottom = it->y_draw + GRANDSTAFF_DISTANCE/2; + break; + case GRAND_BOTTOM: + it->y_draw = it->y_top + GRANDSTAFF_DISTANCE/2; + it->y_bottom = it->y_draw + STAFF_DISTANCE/2; + break; + default: + cout << "THIS SHOULD NEVER HAPPEN: invalid staff type!" << endl; + } + y=it->y_bottom; + } + + emit canvas_height_changed( canvas_height() ); +} -void ScoreEdit::initShortcuts() - { - editCutAction->setShortcut(shortcuts[SHRT_CUT].key); - editCopyAction->setShortcut(shortcuts[SHRT_COPY].key); - editPasteAction->setShortcut(shortcuts[SHRT_PASTE].key); - editDelEventsAction->setShortcut(shortcuts[SHRT_DELETE].key); - - selectAllAction->setShortcut(shortcuts[SHRT_SELECT_ALL].key); - selectNoneAction->setShortcut(shortcuts[SHRT_SELECT_NONE].key); - selectInvertAction->setShortcut(shortcuts[SHRT_SELECT_INVERT].key); - selectInsideLoopAction->setShortcut(shortcuts[SHRT_SELECT_ILOOP].key); - selectOutsideLoopAction->setShortcut(shortcuts[SHRT_SELECT_OLOOP].key); - selectPrevPartAction->setShortcut(shortcuts[SHRT_SELECT_PREV_PART].key); - selectNextPartAction->setShortcut(shortcuts[SHRT_SELECT_NEXT_PART].key); - - eventColor->menuAction()->setShortcut(shortcuts[SHRT_EVENT_COLOR].key); - //evColorBlueAction->setShortcut(shortcuts[ ].key); - //evColorPitchAction->setShortcut(shortcuts[ ].key); - //evColorVelAction->setShortcut(shortcuts[ ].key); - - funcOverQuantAction->setShortcut(shortcuts[SHRT_OVER_QUANTIZE].key); - funcNoteOnQuantAction->setShortcut(shortcuts[SHRT_ON_QUANTIZE].key); - funcNoteOnOffQuantAction->setShortcut(shortcuts[SHRT_ONOFF_QUANTIZE].key); - funcIterQuantAction->setShortcut(shortcuts[SHRT_ITERATIVE_QUANTIZE].key); - - funcConfigQuantAction->setShortcut(shortcuts[SHRT_CONFIG_QUANT].key); - - funcGateTimeAction->setShortcut(shortcuts[SHRT_MODIFY_GATE_TIME].key); - funcModVelAction->setShortcut(shortcuts[SHRT_MODIFY_VELOCITY].key); - funcCrescendoAction->setShortcut(shortcuts[SHRT_CRESCENDO].key); - funcTransposeAction->setShortcut(shortcuts[SHRT_TRANSPOSE].key); - funcThinOutAction->setShortcut(shortcuts[SHRT_THIN_OUT].key); - funcEraseEventAction->setShortcut(shortcuts[SHRT_ERASE_EVENT].key); - funcNoteShiftAction->setShortcut(shortcuts[SHRT_NOTE_SHIFT].key); - funcMoveClockAction->setShortcut(shortcuts[SHRT_MOVE_CLOCK].key); - funcCopyMeasureAction->setShortcut(shortcuts[SHRT_COPY_MEASURE].key); - funcEraseMeasureAction->setShortcut(shortcuts[SHRT_ERASE_MEASURE].key); - funcDelMeasureAction->setShortcut(shortcuts[SHRT_DELETE_MEASURE].key); - funcCreateMeasureAction->setShortcut(shortcuts[SHRT_CREATE_MEASURE].key); - funcSetFixedLenAction->setShortcut(shortcuts[SHRT_FIXED_LEN].key); - funcDelOverlapsAction->setShortcut(shortcuts[SHRT_DELETE_OVERLAPS].key); - - } +list<staff_t>::iterator ScoreCanvas::staff_at_y(int y) +{ + for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) + if ((y >= it->y_top) && (y < it->y_bottom)) + return it; -//--------------------------------------------------------- -// execDeliveredScript -//--------------------------------------------------------- -void ScoreEdit::execDeliveredScript(int id) + return staves.end(); +} + +void ScoreCanvas::play_changed(bool) { - //QString scriptfile = QString(INSTPREFIX) + SCRIPTSSUFFIX + deliveredScriptNames[id]; - QString scriptfile = song->getScriptPath(id, true); - song->executeScript(scriptfile.toAscii().data(), parts(), quant(), true); + redraw(); } -//--------------------------------------------------------- -// execUserScript -//--------------------------------------------------------- -void ScoreEdit::execUserScript(int id) +void ScoreCanvas::config_changed() { - QString scriptfile = song->getScriptPath(id, false); - song->executeScript(scriptfile.toAscii().data(), parts(), quant(), true); + redraw(); } -//--------------------------------------------------------- -// newCanvasWidth -//--------------------------------------------------------- +void ScoreCanvas::set_tool(int tool) +{ + switch (tool) + { + case PointerTool: mouse_erases_notes=false; mouse_inserts_notes=false; break; + case RubberTool: mouse_erases_notes=true; mouse_inserts_notes=false; break; + case PencilTool: mouse_erases_notes=false; mouse_inserts_notes=true; break; + default: + cout << "THIS SHOULD NEVER HAPPEN: set_tool called with unknown tool ("<<tool<<")"<<endl; + } +} -void ScoreEdit::newCanvasWidth(int /*w*/) - { -/* - int nw = w + (vscroll->width() - 18); // 18 is the fixed width of the CtlEdit VScale widget. - if(nw < 1) - nw = 1; - - for (std::list<CtrlEdit*>::iterator i = ctrlEditList.begin(); - i != ctrlEditList.end(); ++i) { - // Changed by Tim. p3.3.7 - //(*i)->setCanvasWidth(w); - (*i)->setCanvasWidth(nw); - } - - updateHScrollRange(); -*/ - } +void ScoreCanvas::menu_command(int cmd) +{ + switch (cmd) + { + case CMD_COLOR_BLACK: coloring_mode=COLOR_MODE_BLACK; redraw(); break; + case CMD_COLOR_PART: coloring_mode=COLOR_MODE_PART; redraw(); break; + case CMD_NOTELEN_1: new_len=TICKS_PER_WHOLE/ 1; break; + case CMD_NOTELEN_2: new_len=TICKS_PER_WHOLE/ 2; break; + case CMD_NOTELEN_4: new_len=TICKS_PER_WHOLE/ 4; break; + case CMD_NOTELEN_8: new_len=TICKS_PER_WHOLE/ 8; break; + case CMD_NOTELEN_16: new_len=TICKS_PER_WHOLE/16; break; + case CMD_NOTELEN_32: new_len=TICKS_PER_WHOLE/32; break; + case CMD_NOTELEN_LAST: new_len=-1; break; + default: + cout << "ILLEGAL FUNCTION CALL: ScoreCanvas::menu_command called with unknown command ("<<cmd<<")"<<endl; + } +} -//--------------------------------------------------------- -// toggleTrackInfo -//--------------------------------------------------------- +void ScoreCanvas::preamble_keysig_slot(bool state) +{ + preamble_contains_keysig=state; + redraw(); +} +void ScoreCanvas::preamble_timesig_slot(bool state) +{ + preamble_contains_timesig=state; + redraw(); +} -void ScoreEdit::toggleTrackInfo() +void ScoreCanvas::set_quant(int val) { - bool vis = midiTrackInfo->isVisible(); - infoScroll->setVisible(!vis); - infoScroll->setEnabled(!vis); + int quant_mapper[]={1,2,3,4,5}; + + if ((val>=0) && (val<signed(sizeof(quant_mapper)/sizeof(*quant_mapper)))) + { + _quant_power2=quant_mapper[val]; + + song_changed(SC_EVENT_INSERTED); + } + else + { + cout << "ILLEGAL FUNCTION CALL: set_quant called with invalid value of "<<val<<endl; + } } + + +//the following assertions are made: +// pix_quarter.width() == pix_half.width() + + +// pix->width()-1 + 1/2*pix->width() + SHIFT + ADD_SPACE +// 10-1+5+3+3=20 <- um so viel wird der taktstrich verschoben +// um das doppelte (20*2=40) werden die kleinsten schläge gegeneinander versetzt + + + + + +//hint: recalculating event- and itemlists "from zero" +// could happen in realtime, as it is pretty fast. +// however, this adds unneccessary cpu usage. +// it is NO problem to recalc the stuff "from zero" +// every time something changes. + + +/* BUGS and potential bugs + * o when color=black, then the tie has a wrong color, because + * partColors[BLACK_INDEX] is out of bounds + * o when the keymap is not used, this will probably lead to a bug + * o when adding a note, it's added to the first stave + * the problem is: there's always the first part selected + * + * CURRENT TODO + * o automatically set x-raster (by quant. strength) + * + * IMPORTANT TODO + * o removing the part the score's working on isn't handled + * o let the user select the currently edited part + * o support selections + * o emit a "song-changed" signal instead of calling our + * internal song_changed() function + * o check if "moving away" works for whole notes [seems to NOT work properly] + * o more fine-grained redrawing in song_changed: sometimes, + * only a redraw and not a recalc is needed + * o do all the song_changed(SC_EVENT_INSERTED) properly + * + * less important stuff + * o must add_parts() update the part-list? + * o support different keys in different tracks at the same time + * calc_pos_add_list and calc_item_pos will be affected by this + * calc_pos_add_list must be called before calc_item_pos then, + * and calc_item_pos must respect the pos_add_list instead of + * keeping its own pos_add variable (which is only an optimisation) + * o use nearest part instead of curr_part, maybe expand + * o draw measure numbers + * o when moving or resizing a note, so that its end is out-of-part, + * there's strange behaviour + * o ties aren't always drawn correctly when the destination note + * is out of view + * o tied notes don't work properly when there's a key-change in + * between, for example, when a cis is tied to a des + * o let the user select whether the preamble should have + * a fixed length (?) + * o let the user select what the preamble has to contain + * > o use timesig_t in all timesig-stuff + * o draw a margin around notes which are in a bright color + * o maybe override color 0 with "black"? + * o use bars instead of flags over groups of 8ths / 16ths etc + * o (change ItemList into map< pos_t , mutable_stuff_t >) [no] + * o deal with expanding parts or clip (expanding is better) + * o refuse to resize so that width gets smaller or equal than x_left + * o add tracks in correct order to score + * + * stuff for the other muse developers + * o process accurate timesignatures from muse's list (has to be implemented first in muse) + * ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 ) + * o maybe do expanding parts inside the msgChangeEvent or + * msgNewEvent functions (see my e-mail) + * + * GUI stuff + * o invalidate len-buttons for lens which are outside of the quantisation setting + * o velocity/release-velo for newly inserted notes [->toolbar] + * o velocity/release-velo for already existing notes + * - do this by right-click -> some dialog shows up? + * - or by selecting the note and changing the values in the same widget which also is used for new notes? + * o initiate "select current part" +*/ + + +/* how to use the score editor with multiple tracks + * ================================================ + * + * select parts, right-click, "display in new score window" or "display per-track in new score window" + * or "display in existing window -> 1,2,3,4" or "display per-track in existing..." + * + * ScoreCanvas has a list of note systems, consisting of the following: + * * all parts included in that view + * * eventlist, itemlist + * * used clef, transposing/octave settings + * * enum { NOT_GROUPED, I_AM_TOP, I_AM_BOTTOM } group_state + * NOT_GROUPED means "single note system" + * I_AM_TOP and I_AM_BOTTOM mean that the two systems belong + * together + * + * when redrawing, we iterate through all systems. + * we add a distance according to group_state + * then we draw the system. if group_state is I_AM_BOTTOM, we + * draw our beams longer/higher, and we draw a bracket + * + * when clicking around, we first determine which system has been clicked in + * (the systems have enough space in between, so there won't be notes + * from sys1 in sys2. if there are, they're ignored for simplicity) + * then we proceed as usual (adding, removing, changing notes) + * + * + * pos_add_list stays the same for each staff, so we only need one + */ + +/* R O A D M A P + * ============= + * + * 1. finish the score editor, without transposing instruments and + * with only a global keymap + * + * REASON: a score editor with few functions is better than + * no score editor at all + * + * + * 2. support transposing by octave-steps + * + * REASON: the main problem with transposing is, that the + * editor needs different key signatures and needs + * to align them against each other. this problem + * doesn't exist when only transposing by octaves + * + * + * 3. support transposing instruments, but only one + * transposing-setting per score window. that is, you won't be + * able to display your (C-)strings in the same window as your + * B-trumpet. this will be very easy to implement + * + * REASON: the above problem still exists, but is circumvented + * by simply not having to align them against each other + * (because they're in different windows) + * + * + * 4. support different transposing instruments in the same score + * window. this will be some hassle, because we need to align + * the scores properly. for example, when the C-violin has + * C-major (no accidentials), then the B-trumpet need some + * accidentials. we now must align the staves so that the + * "note-after-keychange"s of both staves are again at the + * same x-position + * + * REASON: some solution for that problem must be written. + * this is a large step, which atm isn't very important + * + * + * 5. support different keys per track. this wouldn't be that + * hard, when 4) is already done; because we then already have + * the "align it properly" functionality, and can use it + * + * REASON: this is only a nice-to-have, which can however be + * easily implemented when 4) is done + */ + diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 767dc463..c3ba246c 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -1,8 +1,8 @@ //========================================================= // MusE // Linux Music Editor -// $Id: pianoroll.h,v 1.5.2.4 2009/11/16 11:29:33 lunar_shuttle Exp $ -// (C) Copyright 1999 Werner Schweer (ws@seh.de) +// scoreedit.h +// (C) Copyright 2011 Florian Jung (florian.a.jung@web.de) //========================================================= #ifndef __SCOREEDIT_H__ @@ -12,6 +12,11 @@ #include <QResizeEvent> #include <QLabel> #include <QKeyEvent> +#include <QPainter> +#include <QPixmap> +#include <QTimer> +#include <QScrollBar> +#include <QSignalMapper> #include <values.h> #include "noteinfo.h" @@ -19,183 +24,643 @@ #include "midieditor.h" #include "tools.h" #include "event.h" +#include "view.h" +#include "gconfig.h" +#include "part.h" +#include "keyevent.h" -class MidiPart; -class TimeLabel; -class PitchLabel; -class QLabel; -class PianoCanvas; -class MTScale; -class Track; -class QToolButton; -class QToolBar; -class QPushButton; -class CtrlEdit; -class Splitter; -class PartList; -class Toolbar1; -class Xml; -class QuantConfig; -class ScrollScale; -class Part; -class SNode; -class QMenu; -class QAction; -class QWidget; -class QScrollBar; -class MidiTrackInfo; -class QScrollArea; +#include <set> +#include <map> +#include <list> +#include <vector> +#include <string> + +using std::set; +using std::pair; +using std::map; +using std::list; +using std::vector; +using std::string; + + + +#define TICKS_PER_WHOLE (config.division*4) +#define SONG_LENGTH (song->len()) + + + +enum {CMD_COLOR_BLACK, CMD_COLOR_VELO, CMD_COLOR_PART, + CMD_SET_NAME, + CMD_NOTELEN_1, CMD_NOTELEN_2, CMD_NOTELEN_4, CMD_NOTELEN_8, + CMD_NOTELEN_16, CMD_NOTELEN_32, CMD_NOTELEN_LAST }; + +class ScoreCanvas; //--------------------------------------------------------- -// PianoRoll +// ScoreEdit //--------------------------------------------------------- -class ScoreEdit : public MidiEditor { - Event selEvent; - MidiPart* selPart; - int selTick; - - //enum { CMD_EVENT_COLOR, CMD_CONFIG_QUANT, CMD_LAST }; - //int menu_ids[CMD_LAST]; - //Q3PopupMenu *menuEdit, *menuFunctions, *menuSelect, *menuConfig, *menuPlugins; - - - QMenu *menuEdit, *menuFunctions, *menuSelect, *menuConfig, *eventColor, *menuPlugins; - MidiTrackInfo *midiTrackInfo; - Track* selected; - - QAction* editCutAction; - QAction* editCopyAction; - QAction* editPasteAction; - QAction* editDelEventsAction; - - QAction* selectAllAction; - QAction* selectNoneAction; - QAction* selectInvertAction; - QAction* selectInsideLoopAction; - QAction* selectOutsideLoopAction; - QAction* selectPrevPartAction; - QAction* selectNextPartAction; - - QAction* evColorBlueAction; - QAction* evColorPitchAction; - QAction* evColorVelAction; - - QAction* funcOverQuantAction; - QAction* funcNoteOnQuantAction; - QAction* funcNoteOnOffQuantAction; - QAction* funcIterQuantAction; - QAction* funcConfigQuantAction; - QAction* funcGateTimeAction; - QAction* funcModVelAction; - QAction* funcCrescendoAction; - QAction* funcTransposeAction; - QAction* funcThinOutAction; - QAction* funcEraseEventAction; - QAction* funcNoteShiftAction; - QAction* funcMoveClockAction; - QAction* funcCopyMeasureAction; - QAction* funcEraseMeasureAction; - QAction* funcDelMeasureAction; - QAction* funcCreateMeasureAction; - QAction* funcSetFixedLenAction; - QAction* funcDelOverlapsAction; - - - int tickOffset; - int lenOffset; - int pitchOffset; - int veloOnOffset; - int veloOffOffset; - bool deltaMode; - - NoteInfo* info; - QToolButton* srec; - QToolButton* midiin; - - Toolbar1* toolbar; - Splitter* splitter; - Splitter* hsplitter; - Splitter* ctrlLane; - - QToolButton* speaker; - QToolBar* tools; - EditToolBar* tools2; - - int colorMode; - - static int _quantInit, _rasterInit; - static int _widthInit, _heightInit; - - static int _quantStrengthInit; - static int _quantLimitInit; - static bool _quantLenInit; - static int _toInit; - static int colorModeInit; - - int _quantStrength; - int _quantLimit; - int _to; - bool _quantLen; - QuantConfig* quantConfig; - bool _playEvents; - - //QScrollBar* infoScroll; - QScrollArea* infoScroll; - - Q_OBJECT - void initShortcuts(); - void setEventColorMode(int); - QWidget* genToolbar(QWidget* parent); - virtual void closeEvent(QCloseEvent*); - virtual void keyPressEvent(QKeyEvent*); - virtual void resizeEvent(QResizeEvent*); - - private slots: - void setSelection(int, Event&, Part*); - void noteinfoChanged(NoteInfo::ValType, int); - //CtrlEdit* addCtrl(); - void removeCtrl(CtrlEdit* ctrl); - void soloChanged(bool flag); - //void trackInfoScroll(int); - void setRaster(int); - void setQuant(int); - void configQuant(); - void setQuantStrength(int val) { _quantStrength = val; } - void setQuantLimit(int val) { _quantLimit = val; } - void setQuantLen(bool val) { _quantLen = val; } - void cmd(int); - void setSteprec(bool); - void setTo(int val) { _to = val; } - void eventColorModeChanged(int); - void clipboardChanged(); // enable/disable "Paste" - void selectionChanged(); // enable/disable "Copy" & "Paste" - void setSpeaker(bool); - void setTime(unsigned); - void follow(int pos); - void songChanged1(int); - void configChanged(); - void newCanvasWidth(int); - void toggleTrackInfo(); - void updateTrackInfo(); - - signals: - void deleted(unsigned long); - +class ScoreEdit : public MidiEditor +{ + Q_OBJECT + + private: + virtual void closeEvent(QCloseEvent*); + + QScrollBar* xscroll; + QScrollBar* yscroll; + ScoreCanvas* score_canvas; + + static int serial; + static set<QString> names; + + QString name; + + QSignalMapper* menu_mapper; + + bool set_name(QString newname, bool emit_signal=true, bool emergency_name=false); + + private slots: + void menu_command(int); + + signals: + void deleted(unsigned long); + void name_changed(); + + public slots: + void canvas_width_changed(int); + void viewport_width_changed(int); + void canvas_height_changed(int); + void viewport_height_changed(int); + + public: + ScoreEdit(PartList*, QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT); + ~ScoreEdit(); + static void readConfiguration(Xml&){}; //TODO does nothing + static void writeConfiguration(int, Xml&){}; //TODO does nothing + + void add_parts(PartList* pl, bool all_in_one=false); + QString get_name() { return name; } + }; + + + + + + +enum stem_t +{ + UPWARDS, + DOWNWARDS +}; + +enum vorzeichen_t +{ + B=-1, + NONE=0, + SHARP=1 +}; + +struct note_pos_t +{ + int height; // 0 means "C-line", 1 "D-line" and so on + vorzeichen_t vorzeichen; + + bool operator== (const note_pos_t& that) const + { + return (this->height==that.height) && (this->vorzeichen == that.vorzeichen); + } +}; + +bool operator< (const note_pos_t& a, const note_pos_t& b); + + + + + + + +class FloEvent +{ + public: + enum typeEnum { NOTE_ON = 30, NOTE_OFF = 10, BAR = 20, KEY_CHANGE=23, TIME_SIG=26 }; //the order matters! + typeEnum type; + unsigned tick; + Part* source_part; + Event* source_event; + + int pitch; + mutable int vel; + mutable int len; + + int num; + int denom; + + key_enum key; + + + FloEvent(unsigned ti, int p,int v,int l,typeEnum t, Part* part=NULL, Event* event=NULL) + { + pitch=p; + vel=v; + len=l; + type= t; + tick=ti; + source_event=event; + source_part=part; + } + FloEvent(unsigned ti, typeEnum t, int num_, int denom_) + { + type=t; + num=num_; + denom=denom_; + tick=ti; + source_event=NULL; + source_part=NULL; + } + FloEvent(unsigned ti, typeEnum t, key_enum k) + { + type=t; + key=k; + tick=ti; + source_event=NULL; + source_part=NULL; + } +}; +class FloItem +{ + public: + enum typeEnum { NOTE=21, REST=22, NOTE_END=01, REST_END=02, BAR =10, KEY_CHANGE=13, TIME_SIG=16}; //the order matters! + typeEnum type; + unsigned begin_tick; + Event* source_event; + Part* source_part; + + note_pos_t pos; + int len; + int dots; + bool tied; + bool already_grouped; + + int num; + int denom; + + key_enum key; + + mutable stem_t stem; + mutable int shift; + mutable bool ausweich; + mutable bool is_tie_dest; + mutable int tie_from_x; + + mutable int x; + mutable int y; + mutable int stem_x; + mutable QPixmap* pix; + + mutable bool is_active; + + QRect bbox() const; + + + + FloItem(typeEnum t, note_pos_t p, int l=0,int d=0, bool ti=false, unsigned beg=0, Part* part=NULL, Event* event=NULL) + { + pos=p; + dots=d; + len=l; + type=t; + already_grouped=false; + tied=ti; + shift=0; + ausweich=false; + is_tie_dest=false; + begin_tick=beg; + source_event=event; + source_part=part; + } + + FloItem(typeEnum t, int num_, int denom_) + { + type=t; + num=num_; + denom=denom_; + begin_tick=-1; + source_event=NULL; + source_part=NULL; + } + + FloItem(typeEnum t, key_enum k) + { + type=t; + key=k; + begin_tick=-1; + source_event=NULL; + source_part=NULL; + } + + FloItem(typeEnum t) + { + type=t; + + already_grouped=false; + tied=false; + shift=0; + ausweich=false; + is_tie_dest=false; + begin_tick=-1; + source_event=NULL; + source_part=NULL; + } + + FloItem() + { + already_grouped=false; + tied=false; + shift=0; + ausweich=false; + is_tie_dest=false; + begin_tick=-1; + source_event=NULL; + source_part=NULL; + } + + bool operator==(const FloItem& that) + { + if (this->type != that.type) return false; + + switch(type) + { + case NOTE: + case REST: + case NOTE_END: + case REST_END: + return (this->pos == that.pos); + + //the following may only occurr once in a set + //so we don't search for "the time signature with 4/4 + //at t=0", but only for "some time signature at t=0" + //that's why true is returned, and not some conditional + //expression + case BAR: + case KEY_CHANGE: + case TIME_SIG: + return true; + } + } +}; +struct floComp +{ + bool operator() (const pair<unsigned, FloEvent>& a, const pair<unsigned, FloEvent>& b ) + { + if (a.first < b.first) return true; + if (a.first > b.first) return false; + + if (a.second.type<b.second.type) return true; + if (a.second.type>b.second.type) return false; + + return (a.second.pitch<b.second.pitch); + } + bool operator() (const FloItem& a, const FloItem& b ) + { + if (a.type < b.type) return true; + if (a.type > b.type) return false; + + switch(a.type) + { + case FloItem::NOTE: + case FloItem::REST: + case FloItem::NOTE_END: + case FloItem::REST_END: + return (a.pos < b.pos); + + //the following may only occurr once in a set + //so we don't search for "the time signature with 4/4 + //at t=0", but only for "some time signature at t=0" + //that's why true is returned, and not some conditional + //expression + case FloItem::BAR: + case FloItem::KEY_CHANGE: + case FloItem::TIME_SIG: + return false; + } + return (a.pos < b.pos); + } +}; + +typedef set< pair<unsigned, FloEvent>, floComp > ScoreEventList; +typedef map< unsigned, set<FloItem, floComp> > ScoreItemList; + +enum clef_t +{ + VIOLIN, + BASS +}; + + +struct note_len_t +{ + int len; + int dots; + + note_len_t(int l, int d) + { + len=l; dots=d; + } + + note_len_t(int l) + { + len=l; dots=0; + } +}; + +bool operator< (const note_len_t& a,const note_len_t& b); + +struct cumulative_t +{ + int count; + int cumul; + + cumulative_t() + { + count=0; + cumul=0; + } + + void add(int v) + { + count++; + cumul+=v; + } + + float mean() + { + return (float)cumul/count; + } +}; + +#define BLACK_PIXMAP (NUM_PARTCOLORS) +#define HIGHLIGHTED_PIXMAP (NUM_PARTCOLORS+1) + +struct timesig_t +{ + int num; + int denom; +}; + +enum staff_type_t +{ + NORMAL, + GRAND_TOP, + GRAND_BOTTOM +}; + +enum staff_mode_t +{ + MODE_TREBLE, + MODE_BASS, + MODE_BOTH +}; + +struct staff_t +{ + set<Part*> parts; + ScoreEventList eventlist; + ScoreItemList itemlist; + + int y_top; + int y_draw; + int y_bottom; + + staff_type_t type; + clef_t clef; + int split_note; + + ScoreCanvas* parent; + + void create_appropriate_eventlist(const set<Part*>& parts); + void create_itemlist(); + void process_itemlist(); + void calc_item_pos(); + + staff_t(ScoreCanvas* parent_) + { + type=NORMAL; + clef=VIOLIN; + parent=parent_; + } + + staff_t (ScoreCanvas* parent_, staff_type_t type_, clef_t clef_, set<Part*> parts_, int split_note_=0) + { + type=type_; + clef=clef_; + split_note=split_note_; + parts=parts_; + parent=parent_; + } +}; + +list<int> calc_accidentials(key_enum key, clef_t clef, key_enum next_key=KEY_C); +note_pos_t note_pos_(int note, key_enum key); +note_pos_t note_pos (unsigned note, key_enum key, clef_t clef); + +int calc_len(int l, int d); +list<note_len_t> parse_note_len(int len_ticks, int begin_tick, vector<int>& foo, int quant_power2, bool allow_dots=true, bool allow_normal=true); + +int clef_height(clef_t clef); + + +int calc_timesig_width(int num, int denom); +int calc_number_width(int n); + + +class ScoreCanvas : public View +{ + Q_OBJECT + private: + static void load_pixmaps(); + static void draw_pixmap(QPainter& p, int x, int y, const QPixmap& pm); + static void draw_tie (QPainter& p, int x1, int x4, int yo, bool up=true, QColor color=Qt::black); + + static void draw_accidentials(QPainter& p, int x, int y_offset, const list<int>& acc_list, const QPixmap& pix); + + static void draw_timesig(QPainter& p, int x, int y_offset, int num, int denom); + + static void draw_number(QPainter& p, int x, int y, int n); + + + + + + static int height_to_pitch(int h, clef_t clef, key_enum key); + static int height_to_pitch(int h, clef_t clef); + static int y_to_height(int y); + int y_to_pitch(int y, int t, clef_t clef); + + + + + void draw_note_lines(QPainter& p, int y); + void draw_preamble(QPainter& p, int y, clef_t clef); + void draw_items(QPainter& p, int y, staff_t& staff, ScoreItemList::iterator from_it, ScoreItemList::iterator to_it); + void draw_items(QPainter& p, int y, staff_t& staff, int x1, int x2); + void draw_items(QPainter& p, int y, staff_t& staff); + void calc_pos_add_list(); + + + void recalc_staff_pos(); + list<staff_t>::iterator staff_at_y(int y); + + + timesig_t timesig_at_tick(int t); + key_enum key_at_tick(int t); + int tick_to_x(int t); + int x_to_tick(int x); + int calc_posadd(int t); + + + + bool need_redraw_for_hilighting(ScoreItemList::iterator from_it, ScoreItemList::iterator to_it); + bool need_redraw_for_hilighting(ScoreItemList& itemlist, int x1, int x2); + bool need_redraw_for_hilighting(ScoreItemList& itemlist); + bool need_redraw_for_hilighting(); + + + void set_staffmode(list<staff_t>::iterator it, staff_mode_t mode); + void remove_staff(list<staff_t>::iterator it); + void merge_staves(list<staff_t>::iterator dest, list<staff_t>::iterator src); + + +// member variables --------------------------------------------------- + int _quant_power2; + + std::map<int,int> pos_add_list; + + list<staff_t> staves; + + // the drawing area is split into a "preamble" containing clef, + // key and time signature, and the "item's area" containing the + // actual items (notes, bars, rests, etc.) + // x_pos is responsible for scrolling. an item with item->x==x_pos + // will be drawn exactly at the left beginning of the item's area + // x_left could also be called "preamble's width". it defines + // where the item's area begins + // when multiple note systems are drawn into one window, the + // preamble's length is the same for each system + int x_pos; + int x_left; + + int y_pos; + + //for mouse-scrolling + float x_scroll_speed; + float x_scroll_pos; + float y_scroll_speed; + float y_scroll_pos; + + Part* curr_part; + int last_len; + int new_len; //when zero or negative, last_len is used + + QPoint mouse_down_pos; + bool mouse_down; + enum operation_t + { + NO_OP=0, + BEGIN=1, + LENGTH=2, + PITCH=3 + }; + operation_t mouse_operation; + operation_t mouse_x_drag_operation; + bool mouse_erases_notes; + bool mouse_inserts_notes; + + bool dragging; + Part* dragged_event_part; + Event dragged_event; + int dragged_event_original_pitch; + + + + enum {COLOR_MODE_BLACK, COLOR_MODE_PART, COLOR_MODE_PITCH} coloring_mode; + bool preamble_contains_keysig; + bool preamble_contains_timesig; + + + //menu stuff + QAction* staffmode_treble_action; + QAction* staffmode_bass_action; + QAction* staffmode_both_action; + QAction* remove_staff_action; + + QMenu* staff_menu; + list<staff_t>::iterator current_staff; + bool dragging_staff; + + + private slots: + void staffmode_treble_slot(); + void staffmode_bass_slot(); + void staffmode_both_slot(); + void remove_staff_slot(); + + void play_changed(bool); + void config_changed(); + public slots: - virtual void updateHScrollRange(); - void execDeliveredScript(int id); - void execUserScript(int id); - CtrlEdit* addCtrl(); - - public: - ScoreEdit(PartList*, QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT); - ~ScoreEdit(); - virtual void readStatus(Xml&); - virtual void writeStatus(int, Xml&) const; - static void readConfiguration(Xml&); - static void writeConfiguration(int, Xml&); - }; + void x_scroll_event(int); + void y_scroll_event(int); + void song_changed(int); + void goto_tick(int,bool); + void pos_changed(int i, unsigned u, bool b); + void heartbeat_timer_event(); + + void set_tool(int); + void set_quant(int); + void menu_command(int); + void preamble_keysig_slot(bool); + void preamble_timesig_slot(bool); + + signals: + void xscroll_changed(int); + void yscroll_changed(int); + void viewport_width_changed(int); + void canvas_width_changed(int); + void viewport_height_changed(int); + void canvas_height_changed(int); + + protected: + virtual void draw(QPainter& p, const QRect& rect); + MidiEditor* editor; + + virtual void mousePressEvent (QMouseEvent* event); + virtual void mouseMoveEvent (QMouseEvent* event); + virtual void mouseReleaseEvent (QMouseEvent* event); + virtual void resizeEvent(QResizeEvent*); + + public: + ScoreCanvas(MidiEditor*, QWidget*, int, int); + ~ScoreCanvas(){}; + + void add_staves(PartList* pl, bool all_in_one); + + int canvas_width(); + int canvas_height(); + int viewport_width(); + int viewport_height(); + + int quant_power2() { return _quant_power2; } + int quant_len() { return (1<<_quant_power2); } + int quant_ticks() { return TICKS_PER_WHOLE / (1<<_quant_power2); } + int pixels_per_whole() { return 320; } //TODO FINDMICHJETZT + int note_x_indent() { return pixels_per_whole()/quant_len()/2; } +}; + +int calc_measure_len(const list<int>& nums, int denom); +vector<int> create_emphasize_list(const list<int>& nums, int denom); +vector<int> create_emphasize_list(int num, int denom); + #endif diff --git a/muse2/share/CMakeLists.txt b/muse2/share/CMakeLists.txt index aeb7e4a1..44b02269 100644 --- a/muse2/share/CMakeLists.txt +++ b/muse2/share/CMakeLists.txt @@ -29,6 +29,7 @@ subdirs( scripts templates wallpapers + scoreglyphs locale ) diff --git a/muse2/share/scoreglyphs/0.png b/muse2/share/scoreglyphs/0.png Binary files differnew file mode 100644 index 00000000..55e80896 --- /dev/null +++ b/muse2/share/scoreglyphs/0.png diff --git a/muse2/share/scoreglyphs/1.png b/muse2/share/scoreglyphs/1.png Binary files differnew file mode 100644 index 00000000..37cc2f4a --- /dev/null +++ b/muse2/share/scoreglyphs/1.png diff --git a/muse2/share/scoreglyphs/2.png b/muse2/share/scoreglyphs/2.png Binary files differnew file mode 100644 index 00000000..6fbf0b77 --- /dev/null +++ b/muse2/share/scoreglyphs/2.png diff --git a/muse2/share/scoreglyphs/3.png b/muse2/share/scoreglyphs/3.png Binary files differnew file mode 100644 index 00000000..5b896cfe --- /dev/null +++ b/muse2/share/scoreglyphs/3.png diff --git a/muse2/share/scoreglyphs/4.png b/muse2/share/scoreglyphs/4.png Binary files differnew file mode 100644 index 00000000..895fc9dd --- /dev/null +++ b/muse2/share/scoreglyphs/4.png diff --git a/muse2/share/scoreglyphs/5.png b/muse2/share/scoreglyphs/5.png Binary files differnew file mode 100644 index 00000000..1214777c --- /dev/null +++ b/muse2/share/scoreglyphs/5.png diff --git a/muse2/share/scoreglyphs/6.png b/muse2/share/scoreglyphs/6.png Binary files differnew file mode 100644 index 00000000..1113e5b8 --- /dev/null +++ b/muse2/share/scoreglyphs/6.png diff --git a/muse2/share/scoreglyphs/7.png b/muse2/share/scoreglyphs/7.png Binary files differnew file mode 100644 index 00000000..05e01f4f --- /dev/null +++ b/muse2/share/scoreglyphs/7.png diff --git a/muse2/share/scoreglyphs/8.png b/muse2/share/scoreglyphs/8.png Binary files differnew file mode 100644 index 00000000..a9967b92 --- /dev/null +++ b/muse2/share/scoreglyphs/8.png diff --git a/muse2/share/scoreglyphs/9.png b/muse2/share/scoreglyphs/9.png Binary files differnew file mode 100644 index 00000000..d4a23a88 --- /dev/null +++ b/muse2/share/scoreglyphs/9.png diff --git a/muse2/share/scoreglyphs/CMakeLists.txt b/muse2/share/scoreglyphs/CMakeLists.txt new file mode 100644 index 00000000..16617660 --- /dev/null +++ b/muse2/share/scoreglyphs/CMakeLists.txt @@ -0,0 +1,29 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +file (GLOB scoreglyph_files *.png LICENSE) + +subdirs( feta-original + ) + +install( FILES ${scoreglyph_files} + DESTINATION ${MusE_SHARE_DIR}/scoreglyphs + ) + diff --git a/muse2/share/scoreglyphs/LICENSE b/muse2/share/scoreglyphs/LICENSE new file mode 100644 index 00000000..7ff14294 --- /dev/null +++ b/muse2/share/scoreglyphs/LICENSE @@ -0,0 +1,364 @@ +These images can be redistributed and/or modified under the terms +of the GNU General Public License Version 2 as published by the +Free Software Foundation. + +These images is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + + +CREDITS: +these images were taken from lilypond's feta font on 28. March 2011. +they're licensed under the GPL2, as is the feta font (and the whole +lilypond project they belong to), see ./feta-original/COPYING-lilypond + +the relevant original files from the feta font can be found in ./feta-original/ + +a copy of the GPL2, which applies to these images, is attached below: + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/muse2/share/scoreglyphs/acc_b.png b/muse2/share/scoreglyphs/acc_b.png Binary files differnew file mode 100644 index 00000000..1aa3f9e6 --- /dev/null +++ b/muse2/share/scoreglyphs/acc_b.png diff --git a/muse2/share/scoreglyphs/acc_none.png b/muse2/share/scoreglyphs/acc_none.png Binary files differnew file mode 100644 index 00000000..a297eaf2 --- /dev/null +++ b/muse2/share/scoreglyphs/acc_none.png diff --git a/muse2/share/scoreglyphs/acc_sharp.png b/muse2/share/scoreglyphs/acc_sharp.png Binary files differnew file mode 100644 index 00000000..0c8e9eb4 --- /dev/null +++ b/muse2/share/scoreglyphs/acc_sharp.png diff --git a/muse2/share/scoreglyphs/clef_bass_big.png b/muse2/share/scoreglyphs/clef_bass_big.png Binary files differnew file mode 100644 index 00000000..e971a803 --- /dev/null +++ b/muse2/share/scoreglyphs/clef_bass_big.png diff --git a/muse2/share/scoreglyphs/clef_violin_big.png b/muse2/share/scoreglyphs/clef_violin_big.png Binary files differnew file mode 100644 index 00000000..cb170746 --- /dev/null +++ b/muse2/share/scoreglyphs/clef_violin_big.png diff --git a/muse2/share/scoreglyphs/dot.png b/muse2/share/scoreglyphs/dot.png Binary files differnew file mode 100644 index 00000000..e6f3a8f9 --- /dev/null +++ b/muse2/share/scoreglyphs/dot.png diff --git a/muse2/share/scoreglyphs/feta-original/CMakeLists.txt b/muse2/share/scoreglyphs/feta-original/CMakeLists.txt new file mode 100644 index 00000000..04e44107 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/CMakeLists.txt @@ -0,0 +1,27 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +file (GLOB fetaorig_files COPYING-lilypond GNUmakefile README *.pe.in *.mf *.mp) + + +install( FILES ${fetaorig_files} + DESTINATION ${MusE_SHARE_DIR}/scoreglyphs/feta-original + ) + diff --git a/muse2/share/scoreglyphs/feta-original/COPYING-lilypond b/muse2/share/scoreglyphs/feta-original/COPYING-lilypond new file mode 100644 index 00000000..32f7714f --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/COPYING-lilypond @@ -0,0 +1,359 @@ +If you want to redistribute LilyPond, you must comply with the GNU +General Public License (reproduced below). This license applies to +LilyPond with the following exceptions: + +- It does not apply to example input files (which are in +the subdirectory input/) that explicitly specify another license. + +- If you create a document which uses fonts included in LilyPond, and +embed this font or unaltered portions of this font into the document, +then this font does not by itself cause the resulting document to be +covered by the GNU General Public License. This exception does not +however invalidate any other reasons why the document might be covered +by the GNU General Public License. If you modify this font, you may +extend this exception to your version of the font, but you are not +obligated to do so. If you do not wish to do so, delete this exception +statement from your version. + + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/muse2/share/scoreglyphs/feta-original/GNUmakefile b/muse2/share/scoreglyphs/feta-original/GNUmakefile new file mode 100644 index 00000000..389f7b9b --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/GNUmakefile @@ -0,0 +1,198 @@ +# mf/GNUmakefile + +depth = .. + +STEPMAKE_TEMPLATES = metafont \ + install \ + install-out +LOCALSTEPMAKE_TEMPLATES = lilypond + +include $(depth)/make/stepmake.make + + +EXTRA_DIST_FILES += README mf2pt1.mp + +# We don't use $(MF_FILES), because there's more .mf cruft here +FETA_MF_FILES = $(call src-wildcard,feta[0-9]*.mf) \ + $(call src-wildcard,feta-braces-[a-z].mf) \ + $(call src-wildcard,feta-alphabet*[0-9].mf) \ + $(call src-wildcard,parmesan[0-9]*.mf) + +STAFF_SIZES = 11 13 14 16 18 20 23 26 +BRACES = a b c d e f g h i + +OTF_FILES = $(STAFF_SIZES:%=$(outdir)/emmentaler-%.otf) \ + $(outdir)/aybabtu.otf +PE_SCRIPTS = $(STAFF_SIZES:%=$(outdir)/emmentaler-%.pe) +OTF_TABLES = $(STAFF_SIZES:%=$(outdir)/feta%.otf-table) \ + $(BRACES:%=$(outdir)/feta-braces-%.otf-table) +FETA_FONTS = $(FETA_MF_FILES:.mf=) +SVG_FILES = $(OTF_FILES:%.otf=%.svg) + +FC_FIND = $(shell $(FCMATCH) --verbose 'Century Schoolbook L:style=$(1)' \ + | grep 'file:' \ + | sed 's/.*"\([^"]*\)".*/\1/g') + +NCSB_OTFS = $(addprefix $(outdir)/,CenturySchL-Ital.otf \ + CenturySchL-BoldItal.otf \ + CenturySchL-Roma.otf \ + CenturySchL-Bold.otf) +NCSB_INSTALL_DIR = $(local_lilypond_datadir)/fonts/otf + +LOG_FILES = $(FETA_MF_FILES:%.mf=$(outdir)/%.log) +LISP_FILES = $(FETA_MF_FILES:%.mf=$(outdir)/%.lisp) +ENC_FILES = $(FETA_MF_FILES:%.mf=$(outdir)/%.enc) +TFM_FILES = $(FETA_MF_FILES:%.mf=$(outdir)/%.tfm) + +$(outdir)/aybabtu.otf-table: $(BRACES:%=$(outdir)/feta-braces-%.otf-table) + cat $^ > $@ + +$(outdir)/aybabtu.otf-gtable: $(BRACES:%=$(outdir)/feta-braces-%.otf-gtable) + echo '(design_size . 20)' > $@ + + +# only for fonts which +# +# 1. are mentioned in font.scm +# +# 2. are not included with teTeX +# + +$(outdir)/emmentaler-%.otf \ +$(outdir)/emmentaler-%.svg: $(outdir)/emmentaler-%.pe \ + $(outdir)/feta%.pfb \ + $(outdir)/feta-alphabet%.pfb \ + $(outdir)/parmesan%.pfb \ + $(outdir)/feta%.otf-table \ + $(outdir)/feta%.otf-gtable + cd $(outdir) && $(FONTFORGE) -script $(notdir $(basename ,$@).pe) + +$(outdir)/aybabtu.otf \ +$(outdir)/aybabtu.svg: $(outdir)/aybabtu.pe \ + $(foreach s,$(BRACES),$(outdir)/feta-braces-$(s).pfb) \ + $(outdir)/aybabtu.otf-table $(outdir)/aybabtu.otf-gtable + cd $(outdir) && $(FONTFORGE) -script aybabtu.pe + +$(outdir)/%.pfb: $(outdir)/%.log + +$(outdir)/%.otf-table: $(outdir)/%.lisp + cat $< $(if $(findstring brace,$<),,$(subst feta,parmesan,$<)) \ + $(if $(findstring brace,$<),,$(subst feta,feta-alphabet,$<)) > $@ + + +## ugh -- we want this to prevent failing -j2 compiles. +$(outdir)/feta26.otf-table: $(outdir)/feta26.lisp \ + $(outdir)/parmesan26.lisp \ + $(outdir)/feta-alphabet26.lisp +$(outdir)/feta23.otf-table: $(outdir)/feta23.lisp \ + $(outdir)/parmesan23.lisp \ + $(outdir)/feta-alphabet23.lisp +$(outdir)/feta20.otf-table: $(outdir)/feta20.lisp \ + $(outdir)/parmesan20.lisp \ + $(outdir)/feta-alphabet20.lisp +$(outdir)/feta18.otf-table: $(outdir)/feta18.lisp \ + $(outdir)/parmesan18.lisp \ + $(outdir)/feta-alphabet18.lisp +$(outdir)/feta16.otf-table: $(outdir)/feta16.lisp \ + $(outdir)/parmesan16.lisp \ + $(outdir)/feta-alphabet16.lisp +$(outdir)/feta14.otf-table: $(outdir)/feta14.lisp \ + $(outdir)/parmesan14.lisp \ + $(outdir)/feta-alphabet14.lisp +$(outdir)/feta13.otf-table: $(outdir)/feta13.lisp \ + $(outdir)/parmesan13.lisp \ + $(outdir)/feta-alphabet13.lisp +$(outdir)/feta11.otf-table: $(outdir)/feta11.lisp \ + $(outdir)/parmesan11.lisp \ + $(outdir)/feta-alphabet11.lisp + +$(outdir)/aybabtu.otf: $(outdir)/aybabtu.subfonts \ + $(outdir)/aybabtu.fontname \ + $(outdir)/aybabtu.otf-table \ + $(outdir)/aybabtu.otf-gtable \ + $(outdir)/aybabtu.pe + +$(outdir)/aybabtu.otf \ +$(outdir)/aybabtu.svg: $(BRACES:%=$(outdir)/feta-braces-%.pfb) + +$(outdir)/aybabtu.fontname: + echo -n 'aybabtu' > $@ +$(outdir)/aybabtu.subfonts: + echo $(subst .mf,,$(call src-wildcard,feta-braces-[a-z].mf)) > $@ + +$(PE_SCRIPTS): $(buildscript-dir)/gen-emmentaler-scripts + $< --dir=$(outdir) + +ALL_FONTS = $(FETA_FONTS) +PFB_FILES = $(ALL_FONTS:%=$(outdir)/%.pfb) + +# Make tfm files first, log files last, +# so that normally log files aren't made twice +ALL_GEN_FILES = $(LOG_FILES) \ + $(ENC_FILES) \ + $(LISP_FILES) \ + $(OTF_TABLES) \ + $(NCSB_OTFS) \ + $(PFB_FILES) \ + $(OTF_FILES) \ + $(SVG_FILES) + +# PRE_INSTALL=$(MAKE) "$(ALL_GEN_FILES)" + +INSTALLATION_DIR = $(local_lilypond_datadir)/fonts/source +INSTALLATION_FILES = $(MF_FILES) + +INSTALLATION_OUT_SUFFIXES = 1 2 3 + +INSTALLATION_OUT_DIR1 = $(local_lilypond_datadir)/fonts/otf +INSTALLATION_OUT_FILES1 = $(OTF_FILES) \ + $(NCSB_OTFS) + +INSTALLATION_OUT_DIR2 = $(local_lilypond_datadir)/fonts/svg +INSTALLATION_OUT_FILES2 = $(SVG_FILES) + +INSTALLATION_OUT_DIR3 = $(local_lilypond_datadir)/fonts/type1 +INSTALLATION_OUT_FILES3 = $(PFB_FILES) + +export MFINPUTS := .:$(MFINPUTS) + + +default: $(ALL_GEN_FILES) \ + $(outdir)/emmentaler-20.otf \ + tree-regen \ + $(outdir)/fonts.conf + +.PHONY: tree-regen + +# FIXME: temporary hack: must regenerate after building fonts +tree-regen: $(ALL_GEN_FILES) + ${MAKE} -C $(top-build-dir) link-mf-tree + +## +## todo: this also depends on .tfm, FIXME. +$(outdir)/%.lisp \ +$(outdir)/%.otf-gtable \ +$(outdir)/%.enc \ +$(outdir)/%.pe: $(outdir)/%.log + $(buildscript-dir)/mf-to-table \ + --global-lisp=$(outdir)/$(<F:.log=.otf-gtable) \ + --lisp=$(outdir)/$(<F:.log=.lisp) \ + --outdir=$(outdir) \ + --enc $(outdir)/$(<F:.log=.enc) \ + $< + +local-clean: + rm -f mfplain.mem mfplain.log + rm -f *.tfm *.log + + +$(outdir)/fonts.conf: + echo '<fontconfig><dir>'$(shell cd $(outdir); pwd)'</dir></fontconfig>' > $@ + +$(NCSB_OTFS): $(NCSB_SOURCE_FILES) \ + $(auxscript-dir)/pfx2ttf.fontforge + $(foreach i, $(basename $(NCSB_SOURCE_FILES)), \ + $(FONTFORGE) -script $(auxscript-dir)/pfx2ttf.fontforge \ + $(i).pfb $(i).afm $(outdir)/ && ) true + +# eof diff --git a/muse2/share/scoreglyphs/feta-original/README b/muse2/share/scoreglyphs/feta-original/README new file mode 100644 index 00000000..9d52194b --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/README @@ -0,0 +1,125 @@ + +This is a font of music symbols. All MF sources are original. Most of the +documentation is in comments in the MF code. + +Non-square pixels are not supported; with other words, the horizontal and +vertical resolution of the output device must be the same. + +Currently, outline fonts are created by using `autotrace', but we are +already in the process of converting the MF code directly to PostScript code +with a tool called `mf2pt1', which in turn calls `FontForge' to postprocess +the output (mainly to remove outline overlaps and to add hints). + +The recommended calling sequence of mf2pt1 is + + mf2pt1 --rounding=0.0001 <other options> <font> + +You need mf2pt1 version 2.1 or newer. + + +Here some guidelines to assure a clean conversion. + +. Never use `---'. Replace it with `--' together with explicit path + directions (if necessary). + +. Don't use self-intersecting outlines in general since they can confuse + mf2pt1's algorithm to get the orientation of a closed path. Note that + MetaPost's implementation of the `turningnumber' primitive (which would + immediately give the orientation of a path) is severely broken before + version 1.0 of MetaPost, thus some hand-made code in mf2pt1.mp is used + to work around this bug. + +. If outlines intersect, avoid grazing intersections. In case two outlines + intersect in an explicitly defined point, include this point in both + intersecting paths to avoid problems due to rounding errors. + +. Don't use `draw' with a polygonal pen but for straight lines (consisting + of exactly two points). In most cases it is quite easy to emulate `draw' + with an explicit definition of the outline or with `penstroke'. + +. Don't apply transformations after calling `fill' -- for example, don't + mirror `currentpicture'. Instead, transform the path and call `fill' + afterwards. This ensures that mf2pt1 gets the correct outline directions + which is a necessary prerequisite for FontForge's algorithm to remove + overlaps. + + +Some glyph name rules: + +. Most glyph names have the form <group>.<name>, where <group> is defined + with the `fet_begingroup' command, and <name> is given with + `fet_beginchar' (within a `fet_begingroup' block). Example: + `clefs.vaticana.fa'. + +. Sometimes it would be sensible to use negative numbers in glyph names. + However, the `-' character shouldn't be used in a glyph name. Replace it + with `M'. For example, write `rests.M3mensural' instead of + `rests.-3mensural'. + +. Glyphs which exist in both an `up' and `down' version should start the + <name> part with either `u' or `d', respectively. Example: `flags.d3', + `flags.u3'. Glyphs which are neutral w.r.t. the direction, and where + members of the glyph group exist which have `up' and `down' versions, + should start with an `s'. Example: `noteheads.s0re'. + + +Some design rules: + +. Always use smooth curve transitions. Since this is difficult to see in + MetaFont proof sheets (which don't show the tangents) I recommend to call + mf2pt1 like this + + FONTFORGE=foo mf2pt1 ... + + (`foo' should be a non-existent program; this avoids the default + postprocessing). Then call FontForge to inspect the outlines. + +. Use rounded corners. + + +Hints for stem attachment: + +. Stem attachment of glyphs is controlled by two special variables called + `charwx' and `charwy'. Stems can be regarded as (very oblonged) + rectangles with slightly rounded corners. For stems pointing upwards the + lower right corner of this rectangle is attached to the glyph at position + (charwx, charwy). For stems pointing downwards it works analogously but + with the upper left corner, where the position of the attachment point is + additionally reflected horizontally about the center of the glyph -- this + ensures that in most cases charwx and charwy can be set to the same values + for up and down stems even though these are attached at the right/left end + of the note, respectively. To make this more precise, the upper left + corner of a down stem is attached at position (charwd/2 - charwx, charwy), + where `charwd' is an internal metafont variable representing the glyph + width as specified by the `set_char_box' command. + +. In case different stem attachments for upward and downward pointing stems + are needed, two separate glyphs must be defined in the Metafont file; of + course, this also applies if two entirely different shapes are needed. + These have the same name but are prefixed by `u' and `d', respectively + (for `up' and `down', obviously). In each of these glyphs the variables + charwx and charwy must be set accordingly. If, on the other hand, the + attachment point is the `same' for both directions (with the + abovementioned horizontal reflection taken into account), then the prefix + `s' (for `symmetric') should be used. See the existing files for + examples. The numbers in the glyph names refer to the duration of the + note; e.g., `s0cross' in feta-bolletjes.mf defines the notehead for a + whole cross-shaped note (similarly, `s1cross' and `s2cross' are for half + and quarter notes, respectively). + + +Finally, some rules to assure that rasterization at low resolutions gives +good results. Today, this is a minor issue, but in some cases it might show +design flaws. + +. Use `define_whole_pixels' and friends where appropriate. + +. Use `hround' and `vround' consistently. A lot of auxiliary macros are + defined in feta-macros.mf. + +. If a path element is duplicated or shifted, use an integer value for the + offset. + +. Add `eps' for mirrored paths to assure correct MetaFont rasterization. + See the comment and the variables at the end of `feta-params.mf' for + details how vertical symmetry should be achieved. diff --git a/muse2/share/scoreglyphs/feta-original/aybabtu.pe.in b/muse2/share/scoreglyphs/feta-original/aybabtu.pe.in new file mode 100644 index 00000000..0130cff2 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/aybabtu.pe.in @@ -0,0 +1,84 @@ +#!@FONTFORGE@ +# all your brace are belong to us + +Open("feta-braces-b.pfb"); +SelectAll(); +Scale(200, 0, 0); +Generate("feta-braces-b.scale.pfb"); + +Open("feta-braces-c.pfb"); +SelectAll(); +Scale(300, 0, 0); +Generate("feta-braces-c.scale.pfb"); + +Open("feta-braces-d.pfb"); +SelectAll(); +Scale(400, 0, 0); +Generate("feta-braces-d.scale.pfb"); + +Open("feta-braces-e.pfb"); +SelectAll(); +Scale(500, 0, 0); +Generate("feta-braces-e.scale.pfb"); + +Open("feta-braces-f.pfb"); +SelectAll(); +Scale(600, 0, 0); +Generate("feta-braces-f.scale.pfb"); + +Open("feta-braces-g.pfb"); +SelectAll(); +Scale(700, 0, 0); +Generate("feta-braces-g.scale.pfb"); + +Open("feta-braces-h.pfb"); +SelectAll(); +Scale(800, 0, 0); +Generate("feta-braces-h.scale.pfb"); + +Open("feta-braces-i.pfb"); +SelectAll(); +Scale(900, 0, 0); +Generate("feta-braces-i.scale.pfb"); + + +New() + +MergeFonts("feta-braces-a.pfb"); +MergeFonts("feta-braces-b.scale.pfb"); +MergeFonts("feta-braces-c.scale.pfb"); +MergeFonts("feta-braces-d.scale.pfb"); +MergeFonts("feta-braces-e.scale.pfb"); +MergeFonts("feta-braces-f.scale.pfb"); +MergeFonts("feta-braces-g.scale.pfb"); +MergeFonts("feta-braces-h.scale.pfb"); +MergeFonts("feta-braces-i.scale.pfb"); + +SetFontNames("Aybabtu-Regular", "Aybabtu", "Aybabtu Regular", "Regular", "GNU GPL", "@TOPLEVEL_VERSION@"); + +i = 0; +while (i < CharCnt()) + Select(i); +# crashes fontforge, use PUA for now -- jcn +# SetUnicodeValue(i + 0xF0000, 0); +/* +PRIVATE AREA + In the BMP, the range 0xe000 to 0xf8ff will never be assigned to any + characters by the standard and is reserved for private usage. For the + Linux community, this private area has been subdivided further into the + range 0xe000 to 0xefff which can be used individually by any end-user + and the Linux zone in the range 0xf000 to 0xf8ff where extensions are + coordinated among all Linux users. The registry of the characters + assigned to the Linux zone is currently maintained by H. Peter Anvin + <Peter.Anvin@linux.org>. +*/ + SetUnicodeValue(i + 0xE000, 0); + ++i; +endloop + +LoadTableFromFile("LILF", "aybabtu.subfonts") +LoadTableFromFile("LILC", "aybabtu.otf-table") +LoadTableFromFile("LILY", "aybabtu.otf-gtable") + +Generate("aybabtu.otf"); +Generate("aybabtu.svg"); diff --git a/muse2/share/scoreglyphs/feta-original/bigcheese.pe.in b/muse2/share/scoreglyphs/feta-original/bigcheese.pe.in new file mode 100644 index 00000000..46b74f0a --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/bigcheese.pe.in @@ -0,0 +1,44 @@ +#!@FONTFORGE@ + + + +New(); + +# Separate Feta versioning? +# Naming: * expose LilyPond20/LilyPond rather than bigcheese +# * using 20 as Weight works for gnome-font-select widget: gfs +SetFontNames("bigcheese20", "LilyPond", "LilyPond BigCheese 20", "20", "GNU GPL", "@TOPLEVEL_VERSION@"); + +MergeFonts("feta20.pfa"); +MergeFonts("parmesan20.pfa"); + +# load nummer/din after setting PUA. +i = 0; +while (i < CharCnt()) + Select(i); +# crashes fontforge, use PUA for now -- jcn +# SetUnicodeValue(i + 0xF0000, 0); +/* +PRIVATE AREA + In the BMP, the range 0xe000 to 0xf8ff will never be assigned to any + characters by the standard and is reserved for private usage. For the + Linux community, this private area has been subdivided further into the + range 0xe000 to 0xefff which can be used individually by any end-user + and the Linux zone in the range 0xf000 to 0xf8ff where extensions are + coordinated among all Linux users. The registry of the characters + assigned to the Linux zone is currently maintained by H. Peter Anvin + <Peter.Anvin@linux.org>. +*/ + SetUnicodeValue(i + 0xE000, 0); + ++i; +endloop + + +MergeFonts("feta-nummer10.pfa"); +MergeFonts("feta-din14.pfa"); +MergeKern("feta-din14.tfm"); + +LoadTableFromFile("LILC", "feta20.otf-table") + +Generate("bigcheese20.otf"); +Generate("bigcheese20.cff"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-accordion.mf b/muse2/share/scoreglyphs/feta-original/feta-accordion.mf new file mode 100644 index 00000000..f1058000 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-accordion.mf @@ -0,0 +1,445 @@ +% +% feta-accordion.mf -- draw accordion symbols +% +% source file of the GNU LilyPond music typesetter +% +% (c) 1998--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +fet_begingroup ("accordion"); + +% +% These dimensions are the same for all register symbols. +% The different symbols should calculate their other dimensions from them. +% + +accreg_dot_size# := .5 staff_space#; +accreg_linethickness# := 1.3 stafflinethickness#; +accreg_lh# := 1.0 staff_space#; + +define_pixels (accreg_dot_size, accreg_linethickness, accreg_lh); + + +fet_beginchar ("accDiscant", "accDiscant") + save r, pat, lh, lt; + path pat; + + r# = 3/2 accreg_lh#; + define_pixels (r); + + set_char_box (r# + accreg_linethickness# / 2, + r# + accreg_linethickness# / 2, + 0, 2 r# + 0.7 accreg_linethickness#); + + lh = vround (2/3 r); + lt = vround (0.7 accreg_linethickness); + + h := 3 lh + lt; + b := w := (3 lh + hround accreg_linethickness) / 2; + + penpos1 (hround accreg_linethickness, 0); + penpos2 (lt, 90); + penpos3 (hround accreg_linethickness, 180); + penpos4 (lt, 270); + + z1r = (w, h / 2); + z2r = (0, h); + z3r = (-b, h / 2); + z4r = (0, 0); + + penlabels (1, 2, 3, 4); + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if known miterlimit: + fill z1r + .. z2r + .. z3r + .. z4r + .. cycle; + unfill z1l + .. z2l + .. z3l + .. z4l + .. cycle; + else: + pickup pencircle xscaled accreg_linethickness yscaled lt; + draw z1 + .. z2 + .. z3 + .. z4 + .. cycle; + fi; + + pat := z4{right} + .. z1{up} + .. {left}z2; + + pickup penrazor scaled lt rotated 90; + + top z5 = pat intersectionpoint ((0, lh + lt) -- (w, lh + lt)); + z6 = z5 xscaled -1; + bot z7 = pat intersectionpoint ((0, 2 lh) -- (w, 2 lh)); + z8 = z7 xscaled -1; + + labels (5, 6, 7, 8); + + draw z5 + -- z6; + draw z7 + -- z8; +fet_endchar; + + +fet_beginchar ("accDot", "accDot") + set_char_box (accreg_dot_size# / 2, accreg_dot_size# / 2, + accreg_dot_size# / 2, accreg_dot_size# / 2); + + pickup pencircle scaled accreg_dot_size; + + rt x0 = hround (accreg_dot_size / 2); + top y0 = vround (accreg_dot_size / 2); + + drawdot z0; +fet_endchar; + + +fet_beginchar ("accFreebase", "accFreebase") + save r, lh, lt; + + r# = accreg_lh#; + define_pixels (r); + + set_char_box (r# + accreg_linethickness# / 2, + r# + accreg_linethickness# / 2, + 0, 2 r# + 0.7 accreg_linethickness#); + + lh = vround r; + lt = vround (0.7 accreg_linethickness); + + h := 2 lh + lt; + b := w := (2 lh + hround accreg_linethickness) / 2; + + penpos1 (hround accreg_linethickness, 0); + penpos2 (lt, 90); + penpos3 (accreg_linethickness, 180); + penpos4 (lt, 270); + + z1r = (w, h / 2); + z2r = (0, h); + z3r = (-b, h / 2); + z4r = (0, 0); + + penlabels (1, 2, 3, 4); + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if known miterlimit: + fill z1r + .. z2r + .. z3r + .. z4r + .. cycle; + unfill z1l + .. z2l + .. z3l + .. z4l + .. cycle; + else: + pickup pencircle xscaled accreg_linethickness yscaled lt; + draw z1 + .. z2 + .. z3 + .. z4 + .. cycle; + fi; + + pickup penrazor scaled lt rotated 90; + + draw z1 + -- z3; +fet_endchar; + + +fet_beginchar ("accStdbase", "accStdbase") + save r, p, lh, lt; + path pat; + + r# = 2 accreg_lh#; + define_pixels (r); + + set_char_box (r# + accreg_linethickness# / 2, + r# + accreg_linethickness# / 2, + 0, 2 r# + 0.7 accreg_linethickness#); + + lh = vround (1/2 r); + lt = vround (0.7 accreg_linethickness); + + h := 4 lh + lt; + b := w := (4 lh + hround accreg_linethickness) / 2; + + penpos1 (hround accreg_linethickness, 0); + penpos2 (lt, 90); + penpos3 (hround accreg_linethickness, 180); + penpos4 (lt, 270); + + z1r = (w, h / 2); + z2r = (0, h); + z3r = (-b, h / 2); + z4r = (0, 0); + + penlabels (1, 2, 3, 4); + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if known miterlimit: + fill z1r + .. z2r + .. z3r + .. z4r + .. cycle; + unfill z1l + .. z2l + .. z3l + .. z4l + .. cycle; + else: + pickup pencircle xscaled accreg_linethickness yscaled lt; + draw z1 + .. z2 + .. z3 + .. z4 + .. cycle; + fi; + + pat := z4{right} + .. z1{up} + .. {left}z2; + + pickup penrazor scaled lt rotated 90; + + top z5 = pat intersectionpoint ((0, lh + lt) -- (w, lh + lt)); + z6 = z5 xscaled -1; + bot z7 = pat intersectionpoint ((0, 3 lh) -- (w, 3 lh)); + z8 = z7 xscaled -1; + + labels (5, 6, 7, 8); + + draw z1 + -- z3; + draw z5 + -- z6; + draw z7 + -- z8; +fet_endchar; + + +fet_beginchar ("accBayanbase", "accBayanbase") + save lh, lt; + + lh = vround accreg_lh; + lt = vround accreg_linethickness; + + set_char_box (accreg_lh# + accreg_linethickness# / 2, + accreg_lh# + accreg_linethickness# / 2, + 0, 3 accreg_lh# + accreg_linethickness#); + + h := 3 lh + lt; + + draw_rounded_block ((-w, 0), (-w + lt, h), lt); + draw_rounded_block ((w - lt, 0), (w, h), lt); + + pickup penrazor scaled lt rotated 90; + + bot z1 = (-w + lt / 2, 0); + bot z2 = (-w + lt / 2, lh); + bot z3 = (-w + lt / 2, 2 lh); + bot z4 = (-w + lt / 2, 3 lh); + + bot z5 = (w - lt / 2, 0); + bot z6 = (w - lt / 2, lh); + bot z7 = (w - lt / 2, 2 lh); + bot z8 = (w - lt / 2, 3 lh); + + draw z1 + -- z5; + draw z2 + -- z6; + draw z3 + -- z7; + draw z4 + -- z8; +fet_endchar; + + +def def_B (expr w, h) = + pickup pencircle scaled 0.15 linethickness; + + penpos10 (thin, -90); + penpos11 (thin, -90); + penpos12 (thick, 0); + penpos13 (thin, 90); + penpos14 (thin, 90); + + penpos15 (thick, 180); + penpos16 (thin, -90); + penpos17 (thin, -90); + penpos18 (thick, 0); + penpos19 (thick, 0); + + z10 = (0, 0); + z11 = (cOne * w, 0); + z12 = (w, .5 mb * h); + z13 = (cTwo * w, mb * h); + z14 = (2 thick, mb * h); + z15 = (.94 w, h - .5 mt * h); + z16 = z13 + (0, mt * h); + z17 = (0, h); + z18 = (1.5 thick, 0); + z19 = (1.5 thick, h); +enddef; + + +def def_S (expr w, h) = + pickup pencircle scaled 0.03 linethickness; + + penpos1 (thin, 180); + penpos2 (thin, -90); + penpos3 (thick, 0); + penpos4 (.5 thick, 90); + penpos5 (thick, 0); + penpos6 (thin, -90); + penpos7 (thin, 180); + penpos8 (thin, 180); + penpos9 (thin, 0); + + z1 = (0, hs); + z2 = (w / 2, 0); + z3 = (w - .5 thick, .5 mb * h); + z4 = (w / 2, mb * h); + z5 = (.5 thick, h - .5 mt * h); + z6 = (w / 2, h); + z7 = (w, h - hs); + z8 = (0, y2r); + z9 = (w, y6l); + + path bue, bueoverst; + + bue := z2{left} + .. z1{up}; + + t := xpart (bue intersectiontimes (z8l -- z7l)); + + bueoverst := z6{right} + .. z7{down}; +enddef; + + +def def_some_vars = + save hs, mb, mt, thin, thick, height, width, cOne, cTwo; + save bx, hx; + + width = .8 (4 staff_space); + height = 2.4 staff_space; + % URG. smaller sizes should be wider and fatter + % thin = 0.05 staff_space; + % thick = 0.2 staff_space; + + 4 hx + bx = 1.15; + 10 hx + bx = 1; + fatten := designsize * hx + bx * 1.2; + thick := 0.2 staff_space * fatten; + + % urg: mustn't ever go thinner than blot! + thin# := blot_diameter#; + define_pixels (thin); + + hs = 0.4 staff_space; + mb = .53; + mt = .47; + cOne = 0.65; + cTwo = 0.60; +enddef; + + +fet_beginchar ("accOldEE", "accOldEE") + save r, pp, ir, lh, lt, stroke_width; + + r# = staff_space#; + define_pixels (r); + + lr = .4 staff_space - linethickness; + ir = .6 staff_space; + stroke_width = .05 staff_space + .5 linethickness; + + set_char_box (r# + accreg_linethickness# / 2, + r# + accreg_linethickness# / 2, + 0, 2 r# + 0.7 accreg_linethickness#); + + z1 = (0, 0); + z2 = (0, ir); + z3 = (0, -ir); + + penpos1 (blot_diameter, 0); + penpos2 (stroke_width + blot_diameter, 0); + penpos3 (stroke_width + blot_diameter, 0); + + pickup pencircle scaled (lr + blot_diameter); + + for pp := 0 step 45 until 135: + drawdot z2 rotated pp; + drawdot z3 rotated pp; + + penstroke (z2e + -- z1e + -- z3e) rotated pp; + endfor; + + pickup pencircle scaled lr; + + drawdot (0, 0); + + currentpicture := currentpicture shifted (0, h / 2); + + lh = vround (2 r); + lt = vround (0.7 accreg_linethickness); + + h := lh + lt; + b := w := (lh + hround accreg_linethickness) / 2; + + penpos10 (hround accreg_linethickness, 0); + penpos11 (lt, 90); + penpos12 (hround accreg_linethickness, 180); + penpos13 (lt, 270); + + z10r = (w, h / 2); + z11r = (0, h); + z12r = (-b, h / 2); + z13r = (0, 0); + + % penlabels (1, 2, 10, 11, 12, 13); + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if known miterlimit: + fill z10r + .. z11r + .. z12r + .. z13r + .. cycle; + unfill z10l + .. z11l + .. z12l + .. z13l + .. cycle; + else: + pickup pencircle xscaled accreg_linethickness yscaled lt; + draw z10 + .. z11 + .. z12 + .. z13 + .. cycle; + fi; +fet_endchar; + + +fet_endgroup ("accordion"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet.mf new file mode 100644 index 00000000..c3d1f09f --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet.mf @@ -0,0 +1,19 @@ +test := 0; + +staffsize# := design_size * pt#; + +input feta-autometric; +input feta-macros; +input feta-params; + +fet_beginfont ("feta-alphabet", design_size, "fetaNumber"); + +mode_setup; + +number_design_size := design_size / 2; +dynamic_design_size := 14 design_size / 20; + +input feta-nummer-code; +input feta-din-code; + +fet_endfont ("feta-nummer"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet11.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet11.mf new file mode 100644 index 00000000..04ba4e38 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet11.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 11.22; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet13.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet13.mf new file mode 100644 index 00000000..d314f40d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet13.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 12.60; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet14.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet14.mf new file mode 100644 index 00000000..9a1bd2ee --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet14.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 14.14; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet16.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet16.mf new file mode 100644 index 00000000..86eb9c8c --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet16.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 15.87; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet18.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet18.mf new file mode 100644 index 00000000..db216c15 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet18.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 17.82; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet20.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet20.mf new file mode 100644 index 00000000..0affe390 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet20.mf @@ -0,0 +1,7 @@ +% feta-alphabet20.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 20; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet23.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet23.mf new file mode 100644 index 00000000..c8a725e5 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet23.mf @@ -0,0 +1,7 @@ +% feta-alphabet23.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 22.45; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-alphabet26.mf b/muse2/share/scoreglyphs/feta-original/feta-alphabet26.mf new file mode 100644 index 00000000..71af0403 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-alphabet26.mf @@ -0,0 +1,6 @@ +% part of LilyPond's pretty-but-neat music font + +design_size := 25.20; +input feta-alphabet; +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-arrow.mf b/muse2/share/scoreglyphs/feta-original/feta-arrow.mf new file mode 100644 index 00000000..f0c39c78 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-arrow.mf @@ -0,0 +1,169 @@ +% +% feta-arrow.mf -- draw arrow heads +% +% source file of the GNU LilyPond music typesetter +% +% (c) 2005--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +fet_begingroup ("arrowheads"); + +% +% To consider: we could put arrow heads at their real Unicode locations. +% + +% +% Set up paths for upper half of arrow head pointing right. +% CLOSE_PATH is for a closed arrow, OPEN_PATH is for the open arrow. +% OPEN_TENSION sets the tension for the part which forms the path in +% OPEN_PATH. +% + +def set_arrow_paths (expr width, height, open_tension, arrowlinethickness) = + save pat, finalpath; + save tip_angle_o, tip_angle_c, tip_dir_c, tip_dir_o; + save indent; + path pat, open_path, close_path; + pair tip_dir_o, tip_dir_c; + + pickup pencircle scaled arrowlinethickness; + + indent = linethickness / 2; + + lft x1 = -width; + x2 = 0; + top y1 = height; + y2 = 0; + + z4 = z3; + y5 = 0; + x5 = x4 + indent; + + pat := z1 + ..tension open_tension.. z2{right}; + penpos2 (arrowlinethickness, 90); + tip_dir_o := direction 0.0 of pat; + tip_angle_o := angle (tip_dir_o); + penpos1 (arrowlinethickness, 90 + tip_angle_o); + z3 = z1; + penpos3 (arrowlinethickness, tip_angle_o); + + open_path := z1r{tip_dir_o} + .. z2r{right} + .. z2l{left} + .. z1l{-tip_dir_o} + .. z3l + .. cycle; + + pat := z4 + .. z5{down}; + tip_dir_c := direction 0.0 of pat; + tip_angle_c := angle (tip_dir_c); + penpos4 (arrowlinethickness, 90+ tip_angle_c); + penpos5 (arrowlinethickness, 0); + z6 = z5; + penpos6 (arrowlinethickness, 90); + + close_path := z4l{tip_dir_c} + .. z5l{down} + .. z6l{right} + .. z2l{right} + .. z2r{left} + ..tension open_tension.. z1r{-tip_dir_o} + .. z3l + .. cycle; +enddef; + + +fet_beginchar ("open", "open.01"); + set_char_box (staff_space#, 1.6 linethickness# / 2, + 0.5 staff_space#, 0.5 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, + 1.0, 1.6 linethickness); + fill open_path; + open_path := open_path yscaled -1; + fill open_path; + + penlabels (1, 2, 3); + penlabels (4, 5, 6); +fet_endchar; + + +fet_beginchar ("open", "open.0M1"); + set_char_box (1.6 linethickness# / 2, staff_space#, + 0.5 staff_space#, 0.5 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, + 1.0, 1.6 linethickness); + fill open_path; + open_path := open_path yscaled -1; + fill open_path; + currentpicture := currentpicture xscaled -1; +fet_endchar; + + +fet_beginchar ("open", "open.11"); + set_char_box (.5 staff_space#, .5 staff_space#, + 1.0 staff_space#, 1.6 linethickness# / 2); + set_arrow_paths (staff_space, 0.5 staff_space, + 1.0, 1.6 linethickness); + fill open_path; + open_path := open_path yscaled -1; + fill open_path; + currentpicture := currentpicture rotated 90; +fet_endchar; + + +fet_beginchar ("open", "open.1M1"); + set_char_box (.5 staff_space#, .5 staff_space#, + 1.6 linethickness# / 2, 1.0 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, + 1.0, 1.6 linethickness); + fill open_path; + open_path := open_path yscaled -1; + fill open_path; + currentpicture := currentpicture rotated 90; + currentpicture := currentpicture yscaled -1; +fet_endchar; + + +fet_beginchar ("close", "close.01"); + set_char_box (staff_space#, 0, 0.5 staff_space#, 0.5 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter); + fill close_path; + close_path := close_path yscaled -1; + fill close_path; +fet_endchar; + + +fet_beginchar ("close", "close.0M1"); + set_char_box (0, staff_space#, 0.5 staff_space#, 0.5 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter); + fill close_path; + close_path := close_path yscaled -1; + fill close_path; + currentpicture := currentpicture xscaled -1; +fet_endchar; + + +fet_beginchar ("close", "close.11"); + set_char_box (.5 staff_space#, .5 staff_space#, + 1.0 staff_space#, 0.0 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter); + fill close_path; + close_path := close_path yscaled -1; + fill close_path; + currentpicture := currentpicture rotated 90; +fet_endchar; + + +fet_beginchar ("close", "close.1M1"); + set_char_box (.5 staff_space#, .5 staff_space#, + 0.0 staff_space#, 1.0 staff_space#); + set_arrow_paths (staff_space, 0.5 staff_space, 1.5, blot_diameter); + fill close_path; + close_path := close_path yscaled -1; + fill close_path; + currentpicture := currentpicture rotated -90; +fet_endchar; + + +fet_endgroup ("arrowheads"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-autometric.mf b/muse2/share/scoreglyphs/feta-original/feta-autometric.mf new file mode 100644 index 00000000..24a0e1b9 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-autometric.mf @@ -0,0 +1,255 @@ +% +% autometric.mf -- administrative MF routines +% +% source file of the Feta (not an acronym for Font-En-Tja) +% pretty-but-neat music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% Jan Nieuwenhuizen <janneke@gnu.org> +% +% These macros help create ascii logging output +% to automate generation of the lily tables. +% The output should be parsed by the mf-to-table script. + + +message "******************************************************"; +message "Using feta Autometric macros."; +message "order of messages: "; +message " NAME/CODE/BP/WD/DP/HT/WX/WY"; +message "******************************************************"; +message ""; + + +% font or database? +def fet_beginfont (expr name, size, encod) = + font_identifier := name & decimal size; + font_size size; + font_coding_scheme "asis"; + message "@{font@:GNU@:LilyPond@:" & name + & "@:" & decimal size + & "@:" & encod + & "@}"; + message ""; +enddef; + + +def fet_endfont = + message "@{tnof@}"; +enddef; + + +% group or table? +def fet_begingroup (expr name) = +begingroup; + save feta_group; + string feta_group; + + feta_group := name; + + message "@{group@:" & feta_group + & "@}"; + message ""; +enddef; + + +def fet_endgroup (expr name) = + message "@{puorg@:" & name + & "@}"; + message ""; +endgroup; +enddef; + + +def autometric_parameter (expr name, value) = + message "@{parameter@:" & name + & "@:" & decimal value + & "@}"; +enddef; + + +def autometric_output_char = + message "@{char@:" & charnamestr + & "@:" & decimal charcode + & "@:" & decimal charbp + & "@:" & decimal charwd + & "@:" & decimal chardp + & "@:" & decimal charht + & "@:" & decimal charwx + & "@:" & decimal charwy + & "@:" & idstr + & "@}"; +enddef; + + +def hround_pixels (expr sharped) = + hround (sharped * hppp) +enddef; + + +def vround_pixels (expr sharped) = + vround (sharped * vppp) +enddef; + + +def tand (expr alpha) = + (sind alpha / cosd alpha) +enddef; + + +def to_bp (expr num) = + decimal (num * bp_per_pixel) +enddef; + + +% breapth, width, depth, height +% breapth x-depth +def set_char_box (expr b_sharp, w_sharp, d_sharp, h_sharp) = + save scharbp, scharht, scharwd, schardp; + + % some paranoia if someone calls set_char_box (charwd, charbp, ...) + scharbp := b_sharp; + scharht := h_sharp; + schardp := d_sharp; + scharwd := w_sharp; + + charbp := scharbp; + charht := scharht; + chardp := schardp; + charwd := scharwd; + + w := hround (w_sharp * hppp); + b := hround (b_sharp * hppp); + h := vround (h_sharp * vppp); + d := vround (d_sharp * vppp); + + charwx := charwd; + charwy := 0; + + % additions for mf2pt1 (`bbox' is called `glyph_dimensions' starting + % with version 2.4.2) + if known bp_per_pixel: + special "% MF2PT1: bbox " + & to_bp (-b) & " " + & to_bp (-d) & " " + & to_bp (w) & " " + & to_bp (h); + special "% MF2PT1: glyph_dimensions " + & to_bp (-b) & " " + & to_bp (-d) & " " + & to_bp (w) & " " + & to_bp (h); + special "% MF2PT1: font_size " & decimal designsize; + special "% MF2PT1: font_slant " & decimal font_slant_; + + for fvar = "font_identifier", + "font_coding_scheme", + "font_version", + "font_comment", + "font_family", + "font_weight", + "font_unique_id", + "font_name": + if known scantokens (fvar & "_"): + special "% MF2PT1: " + & fvar & " " + & scantokens (fvar & "_"); + fi; + endfor; + + for fvar = "font_underline_position", + "font_underline_thickness": + if known scantokens (fvar & "_"): + special "% MF2PT1: " + & fvar & " " + & scantokens ("decimal " & fvar & "_"); + fi; + endfor; + + special "% MF2PT1: font_fixed_pitch " + & (if font_fixed_pitch_: "1" else: "0" fi); + + % this must come after the `font_size' special + special "% MF2PT1: charwd " & decimal charwd; + fi; +enddef; + + +def no_dimen_beginchar (expr c) = +begingroup; + charcode := if known c: byte c else: 0; fi; + charic := 0; + clearxy; + clearit; + clearpen; + scantokens extra_beginchar; +enddef; + + +% +% we leave the ctrl characters alone. +% +code := 32; + + +% starts just as plain mf's beginchar: +% charcode, +% and then adds: +% charname see below +% id index in lily's table + +% The dimensions are uninitialised; you should use set_char_box manually. +def fet_beginchar (expr name, id_lit) = + save idstr, charnamestr; + save charbp; + save w, b, h, d; + save charwx, charwy; + + string idstr, charnamestr; + charnamestr := name; + idstr := id_lit; + + % addition for mf2pt1 + if known bp_per_pixel: + if known feta_group: + special "% MF2PT1: glyph_name " + & feta_group & "." & idstr; + else: + special "% MF2PT1: glyph_name " & idstr; + fi; + fi; + + no_dimen_beginchar (incr code) name; +enddef; + + +def makebox_with_breapth (text r) = + for y = -d, 0, h: + r ((-b, y), (w, y)); + endfor; + + for x = -b, 0, w: + r ( (x, -d), (x, h)); + endfor; +enddef; + + +% +% override plain endchar. We want a different box. +% +def breapth_endchar = + scantokens extra_endchar; + + if proofing > 0: + makebox_with_breapth (proofrule); + fi; + + chardx := (w + b); % what the heck is chardx + shipit; +endgroup; +enddef; + + +def fet_endchar = + autometric_output_char; + breapth_endchar; +enddef; diff --git a/muse2/share/scoreglyphs/feta-original/feta-banier.mf b/muse2/share/scoreglyphs/feta-original/feta-banier.mf new file mode 100644 index 00000000..46b3b061 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-banier.mf @@ -0,0 +1,550 @@ +% +% feta-banier.mf -- draw flags +% +% source file of the GNU LilyPond music typesetter +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +fet_begingroup ("flags"); + +save outer_path; +path outer_path; + +% +% Flags pointing down overlap with the notehead (in x-direction), so +% the down-flag can be bigger. +% + +upflag_width# = .65 black_notehead_width# + stemthickness# / 2; +downflag_width# = .833 black_notehead_width# + stemthickness# / 2; + +right_upflag_space# = .0 upflag_width#; +right_downflag_space# = .0 downflag_width#; + +% +% Flags pointing down cannot overlap with the notehead in y-direction, +% so they have less slant. +% +% Because of optical illusion, the utmost flag (bottom for +% down-pointing, top for up-pointing) should be smaller than the other +% flags. Adobe Sonata doesn't do this correctly. (Instead they have +% an extension flag, which looks less elegant.) +% + +save hip_thickness, foot_thickness; + +hip_thickness# = 1.0 linethickness# + 0.069 staff_space#; +foot_thickness# = 1.2055 linethickness# + 0.06 staff_space#; + +define_pixels (hip_thickness, foot_thickness); + +% +% Inspired by Adobe Sonata and [Wanske]. +% For example, see POSTSCRIPT Language -- program design, +% page 119, and [Wanske], p 41, 42. +% + +def draw_flag (expr center, flare, dims, hip_depth, foot_wid, + hip_thickness, foot_thickness, show_labels) = + save c; + + clearxy; + + c = 0.7; + + penpos1 (flare, 90); + penpos2 (whatever, 0); + + x2r - x2l = hround (hip_thickness); + + penpos3 (foot_thickness, -20.0); + + z1r = center; + z2r = center + (xpart (dims), -ypart (dims) * hip_depth); + z3r = center + (xpart (dims) * foot_wid, -ypart (dims)); + + x2r := hround x2r; + y2r := vround y2r; + + outer_path := z3r{curl c} + .. z2r{up} + .. {up}z1r; + + if show_labels = 1: + penlabels (1, 2, 3); + fi; + + fill z1l{curl 0} + ..tension 1.1.. z2l{down} + .. {curl c}simple_serif (z3l, z3r, 80) + & outer_path + & z1r + -- cycle; +enddef; + +% +% TODO: calculate intersectpoint (see TeX book, p. 137) +% TODO: calculate incision_depth +% + +def add_flag (expr yoff, flare, hip_wid_multiplier, hip_dep_multiplier, + intersectpoint, hip_thickness, foot_thickness) = +begingroup + save prev_center, prev_xextreme, prev_yextreme; + save rel_foot, ip, center, incision_depth; + save prev_hipwid, prev_footdep, prev_hipdep, wid, dep, hip_dep; + save hip_dep_ratio, foot_wid_ratio; + pair prev_center, center, foot, prev_xextreme, prev_yextreme; + pair ip, rel_foot; + + incision_depth = 1.013; + prev_center = point 2 of outer_path; + prev_xextreme = point 1 of outer_path; + prev_yextreme = point 0 of outer_path; + prev_hipwid = xpart (prev_xextreme - prev_center); + prev_footdep = -ypart (prev_yextreme - prev_center); + prev_hipdep = -ypart (prev_xextreme - prev_center); + ip = point intersectpoint of outer_path; + + wid = prev_hipwid * hip_wid_multiplier; + hip_dep = prev_hipdep * hip_dep_multiplier; + + center = prev_center + (0, yoff); + rel_foot = incision_depth [(wid, hip_dep), ip - center]; + dep = -ypart (rel_foot); + foot_wid_ratio = xpart (rel_foot) / wid; + hip_dep_ratio = hip_dep / dep; + + draw_flag (center, flare, (wid, dep), + hip_dep_ratio, foot_wid_ratio, + hip_thickness, foot_thickness, 0); +endgroup +enddef; + + +fet_beginchar ("8th Flag (up)", "u3"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + + flare = staff_space; + hip_depth_ratio = .72; + foot_width_ratio = .8; + hip_width# = upflag_width# - hip_thickness# / 2; + foot_depth# = 3 staff_space# - blot_diameter# / 2; + define_pixels (hip_width, foot_depth); + + set_char_box (0, + hip_width# + stemthickness# / 2 + right_upflag_space#, + foot_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0,0), flare, (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 1); + + draw_square_block ((-0.5 stemthickness_rounded, -staff_space_rounded), + (0, 0)); +fet_endchar; + + +fet_beginchar ("16th Flag (up)", "u4"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + total_depth# = 3.5 staff_space# - blot_diameter# / 2; + flag_count = 2; + flare = .85 staff_space; + flagspace# = .85 staff_space#; + hip_depth_ratio = .72; + hip_width# = upflag_width# - hip_thickness# / 2; + flagspace# + foot_depth# = total_depth#; + foot_width_ratio = .8; + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, + hip_width# + stemthickness# / 2 + right_upflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -flagspace), flare, (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 1); + + add_flag (flagspace, flare, .97, 1.00, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -2 staff_space_rounded)); +fet_endchar; + + +fet_beginchar ("32nd Flag (up)", "u5"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 3; + total_depth# = 4.25 staff_space#; + flare = .85 staff_space; + flagspace# = .87 staff_space#; + hip_depth_ratio = .72; + hip_width# = upflag_width# - hip_thickness# / 2; + foot_width_ratio = .8; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_upflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -2 flagspace), flare, (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 1); + + add_flag (flagspace, flare, .97, 1.00, 1.25, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, .95, 1.05, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -3 staff_space_rounded)); +fet_endchar; + + +fet_beginchar ("64th Flag (up)", "u6"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 4; + flare = .85 staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .72; + hip_width# = upflag_width# - hip_thickness# / 2; + total_depth# = 5.25 staff_space#; + foot_width_ratio = .8; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_upflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 1); + + add_flag (flagspace, flare, .97, 1.00, 1.3, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, 1.00, 1.00, 1.25, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, .95, 1.05, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -4 staff_space_rounded)); +fet_endchar; + + +fet_beginchar ("128th Flag (up)", "u7"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 5; + flare = .85 staff_space; + flagspace# = .93 staff_space#; + hip_depth_ratio = .72; + hip_width# = upflag_width# - hip_thickness# / 2; + total_depth# = 6.25 staff_space#; + foot_width_ratio = .8; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_upflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 1); + + add_flag (flagspace, flare, .97, 1.00, 1.3, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, 1.00, 1.00, 1.25, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, 1.00, 1.00, 1.25, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, 0.95, 1.05, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -5 staff_space_rounded)); +fet_endchar; + + +fet_beginchar ("8th (down)", "d3"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 1; + flare = staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .72; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 2.85 staff_space#; + foot_width_ratio = .8; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, flagspace, foot_depth); + + set_char_box (0, hip_width# + right_downflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2) + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 0); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -staff_space_rounded)); + + y_mirror_char; +fet_endchar; + + +%%%%%%%% +% +% Single Stroke for Short Appogiatura +% + +fet_beginchar ("grace dash (up)", "ugrace"); + save flare, hip_depth_ratio, hip_width, foot_depth; + + hip_depth_ratio = .72; + flare# = staff_space#; + hip_width# = upflag_width# - hip_thickness# / 2; + foot_depth# = 3 staff_space#; + + define_pixels (hip_width, foot_depth); + + set_char_box (hip_width# * hip_depth_ratio, + hip_width# + right_upflag_space#, + foot_depth# * hip_depth_ratio, -flare#) + + pickup pencircle scaled 1.5 stemthickness; + + z1 = (-b, -d); + z2 = (w, h); + + penpos1 (1.5 stemthickness, angle (z2 - z1) - 90); + penpos2 (1.5 stemthickness, angle (z2 - z1) - 90); + + fill z1l + -- z2l + .. top z2 + .. rt z2 + .. z2r + -- z1r + .. bot z1 + .. lft z1 + .. cycle; + + penlabels (1, 2); +fet_endchar; + + +fet_beginchar ("grace dash (down)", "dgrace"); + save flare, hip_depth_ratio, hip_width, foot_depth; + save total_depth; + + hip_depth_ratio = .72 ; + flare# = .99 staff_space#; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 2.85 staff_space#; + foot_depth# = total_depth#; + foot_width_ratio = .8; + + define_pixels (hip_width, foot_depth); + + set_char_box (hip_width# * hip_depth_ratio, + hip_width# + right_downflag_space#, + foot_depth# * hip_depth_ratio, -flare#) + + pickup pencircle scaled 1.5 stemthickness; + + z1 = (-b, -d); + z2 = (w, h); + + penpos1 (1.5 stemthickness, angle (z2 - z1) - 90); + penpos2 (1.5 stemthickness, angle (z2 - z1) - 90); + + fill z1l + -- z2l + .. top z2 + .. rt z2 + .. z2r + -- z1r + .. bot z1 + .. lft z1 + .. cycle; + + y_mirror_char; +fet_endchar; + + +fet_beginchar ("16th (down)", "d4"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 2; + flare = .8 staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .85; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 3.0 staff_space# - blot_diameter# / 2; + foot_width_ratio = .95; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + set_char_box (0, hip_width# + right_downflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 0); + + add_flag (flagspace, flare, .95, 1.00, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -2 staff_space_rounded)); + + y_mirror_char; +fet_endchar; + + +fet_beginchar ("32nd (down)", "d5"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 3; + flare = .84 staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .85; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 3.85 staff_space#; + foot_width_ratio = .95; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_downflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 0); + + add_flag (flagspace, flare, .97, 1.00, 1.25, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, .95, 1.05, 1.25, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -3 staff_space_rounded)); + + y_mirror_char; +fet_endchar; + + +fet_beginchar ("64th (down)", "d6"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 4; + flare = .8 staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .85; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 4.35 staff_space#; + foot_width_ratio = .98; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_downflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 0); + + add_flag (flagspace, flare, .97, 1.20, 1.175, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, .97, 1.10, 1.175, + hip_thickness, foot_thickness); + add_flag (.98 flagspace, flare, .91, 1.05, 1.2, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -4 staff_space_rounded)); + + y_mirror_char; +fet_endchar; + + +fet_beginchar ("128th (down)", "d7"); + save flare, hip_depth_ratio, hip_width, foot_depth, foot_width_ratio; + save flagspace, total_depth, flag_count; + + flag_count = 5; + flare = .8 staff_space; + flagspace# = .9 staff_space#; + hip_depth_ratio = .85; + hip_width# = downflag_width# - hip_thickness# / 2; + total_depth# = 5.25 staff_space#; + foot_width_ratio = .98; + + (flag_count - 1) * flagspace# + foot_depth# = total_depth#; + define_pixels (hip_width, foot_depth); + define_whole_vertical_pixels (flagspace); + + set_char_box (0, hip_width# + right_downflag_space#, + total_depth# + foot_thickness# / 2, stemthickness# / 2); + + draw_flag ((0, -(flag_count - 1) * flagspace), flare, + (hip_width, foot_depth), + hip_depth_ratio, foot_width_ratio, + hip_thickness, foot_thickness, 0); + + add_flag (flagspace, flare, .97, 1.20, 1.175, + hip_thickness, foot_thickness); + add_flag (flagspace, flare, .97, 1.10, 1.175, + hip_thickness, foot_thickness); + add_flag (.98 flagspace, flare, .91, 1.05, 1.2, + hip_thickness, foot_thickness); + add_flag (.98 flagspace, flare, .91, 1.05, 1.2, + hip_thickness, foot_thickness); + + draw_square_block ((-0.5 stemthickness_rounded, 0), + (0, -5 staff_space_rounded)); + + y_mirror_char; +fet_endchar; + +fet_endgroup ("flags"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-beugel.mf b/muse2/share/scoreglyphs/feta-original/feta-beugel.mf new file mode 100644 index 00000000..c61f756d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-beugel.mf @@ -0,0 +1,147 @@ +% +% feta-beugel.mf -- Staff braces +% +% source file of the Feta (not an acronym for Font-En-Tja) +% pretty-but-neat music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% Jan Nieuwenhuizen <janneke@gnu.org> + + +% We have to reduce the pixel-per-point value to +% support large brace glyphs in case we are using MetaPost +% (which by default sets `hppp' to 49.80244, regardless of +% the used `mag' value) + +if known miterlimit: + bpppix_ := 0.2; % ten times larger than original + + numeric mm, pt, dd, bp, cm, pc, cc, in; + + mm * bpppix_ = 2.83464; + pt * bpppix_ = 0.99626; + dd * bpppix_ = 1.06601; + bp * bpppix_ = 1; + cm * bpppix_ = 28.34645; + pc * bpppix_ = 11.95517; + cc * bpppix_ = 12.79213; + in * bpppix_ = 72; + + hppp := pt; + vppp := pt; +fi; + + +input feta-autometric; +input feta-macros; + +staffsize# := 20 pt#; %% arbitrary + +input feta-params; + +% +% We must let the design increase for each font to make sure that mftrace +% doesn't jack up the resolution too highly for the longer braces. +% + +fet_beginfont ("feta-braces-" & char (97 + font_count), + (font_count + 1) * 20, "fetaBraces"); + +mode_setup; + + +save code, braces_per_font; +code := 64; +braces_per_font := 64; + +def draw_brace (expr height_sharp, width_sharp, slt_sharp, brace_number) = + save pendir, height, width, thin, thick, slt, pat; + save penangle; + pair pendir; + path pat; + + height# := height_sharp; + width# := width_sharp; + slt# := slt_sharp; + + fet_beginchar ("brace number " & decimal (brace_number), + "brace" & decimal (brace_number)) + set_char_box (width#, 0, height# / 2, height# / 2); + + define_pixels (height, width, slt); + thin = 2 slt; + thick = .5 width; + + z2 = .5 [z1, z3]; + y3l = y1 + height / 2; + x3 = x1 + width; + y1 = 0; + x1 = -b; + y0 = y1; + x0 = x1 - 2/6 thin; + + pendir = unitvector (x3 - x1, y3l / 6 - y1); + penangle = angle pendir - 90; + penpos3 (thin, penangle); + penpos2 (thick, angle (z3 - z1) - 90); + penpos1 (2/3 thin, penangle); + + penlabels (1, 2, 3); + labels (0); + + pat := z2r + .. simple_serif (z3r, z3l, 90) + .. z2l + .. z1l{dir (angle (z1r - z1l) - 90)} + .. z0{down} + .. z1r{-dir (angle (z1l - z1r) + 90)} + .. cycle; + pat := subpath (0, 5) of pat + -- subpath (6, 7) of pat + .. cycle; + + fill pat; + fill pat yscaled -1; + fet_endchar; +enddef; + + +save stafflinethickness; +save increment; + +linethickness := 0.5 pt#; +increment := 0.5 pt#; +y := 10 pt#; + +for i := 0 step 1 until font_count: + save number; + + number := braces_per_font * i; + + for j := 0 step 1 until (braces_per_font - 1): + % message "l: "&decimal l; + % note: define_pixels (x) multiplies x by hppp, + % must never get bigger than infinity + y := y + increment; + if y > infinity / hppp: + message "Resolution and/or magnification is too high"; + message "HPPP: "& decimal hppp &" Y: " & decimal y; + errmessage "please report to <bug-lilypond@gnu.org>"; + fi; + + % x should be about one staff space, taking brace to have + % default height of 3 staffs, this yields height / 3 / 4 = 12 + % but 15 looks better + x := y / 15; + + increment := x / 10; + linethickness := min (0.5 pt#, y / 150); + if i = font_count: + draw_brace (y, x, linethickness, number); + fi; + + number := number + 1; + endfor; +endfor; + +fet_endfont ("feta-braces"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-bolletjes.mf b/muse2/share/scoreglyphs/feta-original/feta-bolletjes.mf new file mode 100644 index 00000000..fcda6009 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-bolletjes.mf @@ -0,0 +1,1497 @@ +% -*-Fundamental-*- +% feta-bolletjes.mf -- implement noteheads +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org> +% & Han-Wen Nienhuys <hanwen@xs4all.nl> +% & Juergen Reuter <reuter@ipd.uka.de> +% + +test_outlines := 0; + + +save remember_pic; +picture remember_pic; + + +% Most beautiful noteheads are pronounced, not circular, +% and not even symmetric. +% These examples are inspired by [Wanske]; see literature list. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% NOTE HEAD VARIABLES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +save black_notehead_width, noteheight; +save half_notehead_width, whole_notehead_width, slash_thick; +save slash_slope, overdone_heads, solfa_noteheight; + +numeric noteheight; +numeric slash_thick; +numeric black_notehead_width; +numeric whole_notehead_width; +numeric half_notehead_width; + + +fet_begingroup ("noteheads"); + + +% Slope of slash. From scm/grob-description.scm. How to auto-copy? +slash_slope := 1.7; + +% Thickness of slash lines. Quarter notes get 1.5slt width. +slash_thick# := 2/3 * 0.48 staff_space#; + + +% +% Hand-engraved music often has balls extending above and below +% the lines. If you like that, modify overdone heads (unit: +% stafflinethickness). +% +overdone_heads = 0.0; +noteheight# := staff_space# + (1 + overdone_heads) * stafflinethickness#; + + +% +% solfa heads should not overlap on chords. +% +solfa_noteheight# := staff_space# - stafflinethickness#; + +define_pixels (slash_thick); +define_whole_vertical_pixels (noteheight); + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% SLANT moves both extrema on the long axis (by SLANT * ELLIPTICITY, +% so SLANT = -1, puts the extreme on the long axis next to the short +% axis one). +% + +def draw_outside_ellipse (expr ellipticity, tilt, superness, slant) = + save attachment_y; + save pat; + path pat; + + pat := superellipse ((ellipticity, 0), (-slant * ellipticity, 1.0), + (-ellipticity, 0), (slant * ellipticity, -1.0), + superness); + pat := pat rotated tilt; + + save top_point, right_point; + pair top_point, right_point; + + top_point := directionpoint left of pat; + right_point := directionpoint up of pat; + + save scaling, width; + + scaling# = noteheight# / (2 ypart (top_point)); + width# := 2 xpart (right_point) * scaling#; + define_pixels (scaling, width); + + set_char_box (0, width#, noteheight# / 2, noteheight# / 2); + + d := d - feta_space_shift; + + % attachment Y + charwy := ypart (right_point) * scaling#; + charwx := width#; + + pat := pat scaled scaling shifted (w / 2, .5 (h - d)); + + width := hround width; + + if test_outlines = 1: + draw pat; + else: + fill pat; + fi; +enddef; + + +def undraw_inside_ellipse (expr ellipticity, tilt, superness, clearance) = +begingroup + save pat; + path pat; + + pat := superellipse ((ellipticity, 0), (0, 1.0), + (-ellipticity, 0), (0, -1.0), + superness); + pat := pat rotated tilt; + + save top_point, right_point; + pair top_point, right_point; + + top_point := directionpoint left of pat; + right_point := directionpoint up of pat; + + save height, scaling; + + height# = staff_space# + stafflinethickness# - clearance; + scaling# = height# / (2 ypart (top_point)); + define_pixels (scaling); + pat := pat scaled scaling shifted (w / 2, .5 (h - d)); + + if test_outlines = 1: + draw pat; + else: + unfill pat; + fi +endgroup; +enddef; + + +% +% dimensions aren't entirely right. +% +def draw_longa (expr up) = + save stemthick, fudge; + + stemthick# = 2 stafflinethickness#; + define_whole_blacker_pixels (stemthick); + + fudge = hround (blot_diameter / 2); + + draw_outside_ellipse (1.80, 0, 0.707, 0); + undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#); + + pickup pencircle scaled stemthick; + + if up: + bot y1 = -d; + top y2 = h; + rt x1 - fudge = 0; + x1 = x2; + + fudge + lft x3 = w; + x4 = x3; + top y4 = h + 3.0 staff_space; + y3 = y1; + else: + bot y1 = -d - 3.0 staff_space; + top y2 = h; + rt x1 - fudge = 0; + x1 = x2; + + fudge + lft x3 = w; + x4 = x3; + y4 = y2; + bot y3 = -d; + fi; + + draw_gridline (z1, z2, stemthick); + draw_gridline (z3, z4, stemthick); + + labels (1, 2, 3, 4); +enddef; + + +fet_beginchar ("Longa notehead", "uM2"); + draw_longa (true); + + draw_staff (-2, 2, 0); +fet_endchar; + +fet_beginchar ("Longa notehead", "dM2"); + draw_longa (false); + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Longa notehead", "uM2"); + draw_longa (true); + + draw_staff (-2, 2, 0.5); + fet_endchar; + + fet_beginchar ("Longa notehead", "dM2"); + draw_longa (false); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +% +% dimensions aren't entirely right. +% +def draw_brevis = + save stemthick, fudge; + + stemthick# = 2 stafflinethickness#; + define_whole_blacker_pixels (stemthick); + + fudge = hround (blot_diameter / 2); + + draw_outside_ellipse (1.80, 0, 0.707, 0); + undraw_inside_ellipse (1.30, 125, 0.68, 2 stafflinethickness#); + + pickup pencircle scaled stemthick; + + bot y1 = -d; + top y2 = h; + rt x1 - fudge = 0; + x1 = x2; + + fudge + lft x3 = w; + x4 = x3; + y4 = y2; + y3 = y1; + + draw_gridline (z1, z2, stemthick); + draw_gridline (z3, z4, stemthick); +enddef; + + +fet_beginchar ("Brevis notehead", "sM1"); + draw_brevis; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Brevis notehead", "sM1"); + draw_brevis; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Whole notehead", "s0"); + draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, 0.707, 0); + undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10, + 0.68, 2 stafflinethickness#); + + whole_notehead_width# := charwd; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Whole notehead", "s0"); + draw_outside_ellipse (1.80 - puff_up_factor / 3.0, 0, + 0.707, 0); + undraw_inside_ellipse (1.30, 125 - puff_up_factor * 10, + 0.68, 2 stafflinethickness#); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Half notehead", "s1"); + draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, 0.66, 0.17); + undraw_inside_ellipse (3.25, 33, 0.81, 2.5 stafflinethickness#); + + half_notehead_width# := charwd; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Half notehead", "s1"); + draw_outside_ellipse (1.53 - puff_up_factor / 3.0, 34, + 0.66, 0.17); + undraw_inside_ellipse (3.25, 33, 0.81, + 2.5 stafflinethickness#); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Quart notehead", "s2"); + % used to have 32. With 31, they are slightly bolder. + draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31, 0.707, 0); + black_notehead_width# := charwd; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Quart notehead", "s2"); + draw_outside_ellipse (1.49 - puff_up_factor / 3.0, 31, + 0.707, 0); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +fet_beginchar ("Whole diamondhead", "s0diamond"); + draw_outside_ellipse (1.80, 0, 0.495, 0); + undraw_inside_ellipse (1.30, 125, 0.6, + .4 staff_space# + stafflinethickness#); + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Whole diamondhead", "s0diamond"); + draw_outside_ellipse (1.80, 0, 0.495, 0); + undraw_inside_ellipse (1.30, 125, 0.6, + .4 staff_space# + stafflinethickness#); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Half diamondhead", "s1diamond"); + draw_outside_ellipse (1.50, 34, 0.49, 0.17); + undraw_inside_ellipse (3.5, 33, 0.80, + .3 staff_space# + 1.5 stafflinethickness#); + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Half diamondhead", "s1diamond"); + draw_outside_ellipse (1.50, 34, 0.49, 0.17); + undraw_inside_ellipse (3.5, 33, 0.80, + .3 staff_space# + + 1.5 stafflinethickness#); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Quart diamondhead", "s2diamond"); + draw_outside_ellipse (1.80, 35, 0.495, -0.25); + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Quart diamondhead", "s2diamond"); + draw_outside_ellipse (1.80, 35, 0.495, -0.25); + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +vardef penposx@# (expr d) = +begingroup; + save pat; + path pat; + + pat = top z@# + .. lft z@# + .. bot z@# + .. rt z@# + .. cycle; + z@#l = pat intersectionpoint (z@# -- infinity * dir (d + 180)); + z@#r = pat intersectionpoint (z@# -- infinity * dir (d)); +endgroup +enddef; + + +% +% UGH: xs not declared as argument. +% +def define_triangle_shape (expr stemdir) = + save triangle_a, triangle_b, triangle_c; + save triangle_out_a, triangle_out_b, triangle_out_c; + save triangle_in, triangle_out; + save width, depth, height; + save origin, left_up_dir; + save exact_left_point, exact_right_point, exact_down_point; + + path triangle_a, triangle_b, triangle_c; + path triangle_out_a, triangle_out_b, triangle_out_c; + path triangle_in, triangle_out; + pair origin, left_up_dir; + pair exact_down_point, exact_left_point, exact_right_point; + + save pen_thick; + pen_thick# = stafflinethickness# + .1 staff_space#; + define_pixels (llap); + define_blacker_pixels (pen_thick); + + left_up_dir = llap# * dir (90 + tilt); + + xpart (left_up_dir) * xs - (pen_thick# * xs) / 2 + xpart origin = 0; + ypart origin = 0; + + exact_left_point := origin + (left_up_dir xscaled xs); + exact_down_point := origin + (left_up_dir rotated 120 xscaled xs); + exact_right_point := origin + (left_up_dir rotated 240 xscaled xs); + + height# = ypart (exact_left_point + origin) + pen_thick# / 2; + depth# = -ypart (exact_down_point + origin) + pen_thick# / 2; + width# = xpart (exact_right_point - exact_left_point) + + pen_thick# * xs; + + set_char_box (0, width#, depth#, height#); + + % Formerly, the shape has simply been drawn with an elliptical pen + % (`scaled pen_thick xscaled xs'), but the envelope of such a curve + % is of 6th degree. For the sake of mf2pt1, we approximate it. + + pickup pencircle scaled pen_thick xscaled xs; + + z0 = (hround_pixels (xpart origin), 0); + + z1 = z1' = z0 + llap * dir (90 + tilt) xscaled xs; + z2 = z2' = z0 + llap * dir (90 + tilt + 120) xscaled xs; + z3 = z3' = z0 + llap * dir (90 + tilt + 240) xscaled xs; + + z12 = caveness [.5[z1, z2], z3]; + z23 = caveness [.5[z2, z3], z1]; + z31 = caveness [.5[z3, z1], z2]; + + triangle_a = z1 .. z12 .. z2; + triangle_b = z2 .. z23 .. z3; + triangle_c = z3 .. z31 .. z1; + + penposx1 (angle (direction 0 of triangle_a) - 90); + penposx2 (angle (direction 0 of triangle_b) - 90); + penposx3 (angle (direction 0 of triangle_c) - 90); + + penposx1' (angle (direction infinity of triangle_c) + 90); + penposx2' (angle (direction infinity of triangle_a) + 90); + penposx3' (angle (direction infinity of triangle_b) + 90); + + penposx12 (angle (z12 - z0)); + penposx23 (angle (z23 - z0)); + penposx31 (angle (z31 - z0)); + + z10 = (z0 -- z1) intersectionpoint (z1l .. z12l .. z2'r); + z20 = (z0 -- z2) intersectionpoint (z2l .. z23l .. z3'r); + z30 = (z0 -- z3) intersectionpoint (z3l .. z31l .. z1'r); + + triangle_in = z10 + .. z12l + .. z20 + & z20 + .. z23l + .. z30 + & z30 + .. z31l + .. z10 + & cycle; + + triangle_out_a = z1r .. z12r .. z2'l; + triangle_out_b = z2r .. z23r .. z3'l; + triangle_out_c = z3r .. z31r .. z1'l; + + triangle_out = top z1 + .. lft z1 + .. z1r{direction 0 of triangle_out_a} + & triangle_out_a + & {direction infinity of triangle_out_a}z2'l + .. lft z2 + .. bot z2 + .. z2r{direction 0 of triangle_out_b} + & triangle_out_b + & {direction infinity of triangle_out_b}z3'l + .. rt z3 + .. top z3 + .. z3r{direction 0 of triangle_out_c} + & triangle_out_c + & {direction infinity of triangle_out_c}z1'l + .. cycle; + + labels (0, 10, 20, 30); + penlabels (1, 1', 2, 2', 3, 3', 12, 23, 31); + + % attachment Y + if stemdir = 1: + charwy := ypart exact_right_point; + charwx := xpart exact_right_point + .5 pen_thick# * xs; + else: + charwy := -ypart exact_down_point; + charwx := width# - (xpart exact_down_point - .5 pen_thick# * xs); + fi +enddef; + + +def draw_whole_triangle_head = + save hei, xs; + save llap; + save tilt; + + tilt = 40; + llap# = 3/4 noteheight#; + + xs = 1.5; + caveness := 0.1; + define_triangle_shape (1); + fill triangle_out; + unfill triangle_in; +enddef; + + +fet_beginchar ("Whole trianglehead", "s0triangle"); + draw_whole_triangle_head; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Whole trianglehead", "s0triangle"); + draw_whole_triangle_head; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +def draw_small_triangle_head (expr dir) = + save hei, xs; + save llap; + save tilt; + + tilt = 40; + llap# = 2/3 noteheight#; + xs = 1.2; + caveness := 0.1; + define_triangle_shape (dir); + + pickup feta_fillpen; + + filldraw triangle_out; + unfilldraw triangle_in; +enddef; + + +fet_beginchar ("Half trianglehead (downstem)", "d1triangle"); + draw_small_triangle_head (-1); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Half trianglehead (upstem)", "u1triangle"); + draw_small_triangle_head (1); + + draw_staff (-2, 2, 0.5); +fet_endchar; + + +def draw_closed_triangle_head (expr dir) = + save hei, xs; + save llap; + save tilt; + + tilt = 40; + llap# = 2/3 noteheight#; + xs = 1.0; + caveness := 0.1; + define_triangle_shape (dir); + fill triangle_out; +enddef; + + +fet_beginchar ("Quart trianglehead (upstem)", "u2triangle"); + draw_closed_triangle_head (1); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Quart trianglehead (downstem)", "d2triangle"); + draw_closed_triangle_head (-1); + + draw_staff (-2, 2, 0.5); +fet_endchar; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Slash heads are for indicating improvisation. They are +% twice as high as normal heads. +% +def draw_slash (expr hwid_hash) = + save exact_height; + save ne, nw_dist; + pair ne, nw_dist; + exact_height = staff_space# + stafflinethickness# / 2; + + set_char_box (0, 2 exact_height / slash_slope + hwid_hash, + exact_height, exact_height); + + charwx := charwd; + charwy := charht; + + clearxy; + + d := d - feta_shift; + + pickup pencircle scaled blot_diameter; + + bot y1 = -d; + top y2 = h; + lft x1 = 0; + lft x2 = 2 h / slash_slope; + + rt x3 = w; + y3 = y2; + y4 = y1; + x3 - x2 = x4 - x1; + + ne = unitvector (z3 - z4); + nw_dist = (ne rotated 90) * 0.5 blot_diameter; + + fill bot z1{left} + .. (z1 + nw_dist){ne} + -- (z2 + nw_dist){ne} + .. top z2{right} + -- top z3{right} + .. (z3 - nw_dist){-ne} + -- (z4 - nw_dist){-ne} + .. bot z4{left} + -- cycle; + + if hwid_hash > 2 slash_thick#: + save th; + + th = slash_thick - blot_diameter; + y6 = y7; + y5 = y8; + y3 - y7 = th; + y5 - y1 = th; + z6 - z5 = whatever * ne; + z8 - z7 = whatever * ne; + + z5 = z1 + whatever * ne + th * (ne rotated -90); + z8 = z4 + whatever * ne + th * (ne rotated 90); + + unfill z5 + -- z6 + -- z7 + -- z8 + -- cycle; + fi + labels (range 1 thru 10); +enddef; + + +fet_beginchar ("Whole slashhead", "s0slash"); + draw_slash (4 slash_thick# + 0.5 staff_space#); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Half slashhead", "s1slash"); + draw_slash (3.0 slash_thick# + 0.15 staff_space#); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Quart slashhead", "s2slash"); + draw_slash (1.5 slash_thick#); + + draw_staff (-2, 2, 0); +fet_endchar; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% `thick' is the distance between the NE/SW parallel lines in the cross +% (distance between centres of lines) in multiples of stafflinethickness +% +def draw_cross (expr thick) = + save ne, nw; + save ne_dist, nw_dist, rt_dist, up_dist; + save crz_in, crz_out; + save thickness; + pair ne, nw; + pair ne_dist, nw_dist, rt_dist, up_dist; + path crz_in, crz_out; + + pen_thick# := 1.2 stafflinethickness#; + thickness# := thick * stafflinethickness#; + define_pixels (thickness); + define_blacker_pixels (pen_thick); + + pickup pencircle scaled pen_thick; + + h := h - feta_shift; + + top y3 = h; + ne = unitvector ((1, (2 h - pen_thick) / (w - pen_thick))); + rt x4 = w / 2; + y5 = 0; + z4 - z5 = whatever * ne; + x6 = 0; + z6 - z3 = whatever * ne; + z3 - z4 = whatever * (ne yscaled -1); + + z4 - z3 = whatever * (ne) + (ne rotated -90) * thickness; + + + x1 = charwd / 2 - .5 pen_thick#; + z1 = whatever * ne + + thick / 2 * stafflinethickness# * (ne rotated -90); + + % labels (1, 2, 3, 4, 5, 6); + + nw = unitvector (z3 - z4); + + up_dist = up * 0.5 pen_thick / cosd (angle (ne)); + rt_dist = right * 0.5 pen_thick / sind (angle (ne)); + nw_dist = (ne rotated 90) * 0.5 pen_thick; + ne_dist = (nw rotated -90) * 0.5 pen_thick; + + x4' := x4; + x5' := x5; + y6' := y6; + + x4 := hround (x4' + .5 pen_thick) - .5 pen_thick; + x5 := hfloor (x5' + xpart rt_dist) - xpart rt_dist; + y6 := vfloor (y6' + ypart up_dist) - ypart up_dist; + + crz_out = (z6 + up_dist) + -- (z3 + nw_dist){ne} + .. (top z3) + .. (z3 + ne_dist){-nw} + -- (z4 + ne_dist){-nw} + .. (rt z4) + .. (z4 - nw_dist){-ne} + -- (z5 + rt_dist); + crz_out := crz_out shifted (0, feta_shift) + -- reverse crz_out yscaled -1 shifted (0, -feta_eps); + fill crz_out + -- reverse crz_out xscaled -1 shifted (-feta_eps, 0) + -- cycle; + + if (thick > 1): + x4 := hround (x4' - xpart rt_dist) + xpart rt_dist; + x5 := hceiling (x5' - .5 pen_thick) + .5 pen_thick; + y6 := vfloor (y6' - .5 pen_thick) + .5 pen_thick; + + crz_in = (bot z6){right} + .. (z6 - nw_dist){ne} + -- (z3 - up_dist) + -- (z4 - rt_dist) + -- (z5 + nw_dist){-ne} + .. {down}(lft z5); + crz_in := crz_in shifted (0, feta_shift) + -- reverse crz_in yscaled -1 shifted (0, -feta_eps); + unfill crz_in + -- reverse crz_in xscaled -1 shifted (-feta_eps, 0) + -- cycle; + fi + + % ugh + currentpicture := currentpicture shifted (hround (w / 2), 0); + + charwx := charwd; + charwy := y1 + feta_shift; + + z12 = (charwx * hppp, y1 * vppp); + + labels (12); +enddef; + + +fet_beginchar ("Whole Crossed notehead", "s0cross"); + save wid, hei; + + wid# := black_notehead_width# + 4 stafflinethickness#; + hei# := noteheight# + stafflinethickness#; + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + draw_cross (3.75); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Whole Crossed notehead", "s0cross"); + save wid, hei; + + wid# := black_notehead_width# + 4 stafflinethickness#; + hei# := noteheight# + stafflinethickness#; + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + currentpicture := remember_pic; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Half Crossed notehead", "s1cross"); + save wid, hei; + + wid# := black_notehead_width# + 2 stafflinethickness#; + hei# := noteheight# + stafflinethickness# / 2; + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + draw_cross (3.0); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Half Crossed notehead", "s1cross"); + save wid, hei; + + wid# := black_notehead_width# + 2 stafflinethickness#; + hei# := noteheight# + stafflinethickness# / 2; + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + currentpicture := remember_pic; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("Crossed notehead", "s2cross"); + wid# := black_notehead_width#; + hei# := noteheight#; + set_char_box (0, wid#, hei# / 2, hei# / 2); + + draw_cross (1.0); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("Crossed notehead", "s2cross"); + wid# := black_notehead_width#; + hei# := noteheight#; + set_char_box (0, wid#, hei# / 2, hei# / 2); + + currentpicture := remember_pic; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +fet_beginchar ("X-Circled notehead", "s2xcircle"); + save wid, hei; + save cthick, cxd, cyd, dy; + + wid# := black_notehead_width# * sqrt (sqrt2); + hei# := noteheight# * sqrt (sqrt2); + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + d := d - feta_space_shift; + + cthick# := (1.2 + 1/4) * stafflinethickness#; + define_blacker_pixels (cthick); + + cxd := w - cthick; + cyd := h + d - cthick / 2; + + dy = .5 (h - d); + + pickup pencircle scaled cthick; + + fill fullcircle xscaled (cxd + cthick) + yscaled (cyd + cthick) + shifted (w / 2, dy); + unfill fullcircle xscaled (cxd - cthick) + yscaled (cyd - cthick) + shifted (w / 2, dy); + + xpos := .5 cxd / sqrt2; + ypos := .5 cyd / sqrt2; + + pickup penrazor scaled cthick rotated (angle (xpos, ypos) + 90); + draw (-xpos + w / 2, -ypos + dy) -- (xpos + w / 2, ypos + dy); + + pickup penrazor scaled cthick rotated (angle (xpos, -ypos) + 90); + draw (-xpos + w / 2, ypos + dy) -- (xpos + w / 2, -ypos + dy); + + charwx := charwd; + charwy := 0; + + z12 = (charwx * hppp, charwy * vppp); + labels (12); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +if test > 0: + fet_beginchar ("X-Circled notehead", "s2xcircle"); + save wid, hei; + save cthick, cxr, cyr; + + wid# := black_notehead_width# * sqrt (sqrt2); + hei# := noteheight# * sqrt (sqrt2); + + set_char_box (0, wid#, hei# / 2, hei# / 2); + + currentpicture := remember_pic; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; + + +%%%%%%%% +% +% SOLFA SHAPED NOTES +% + +save solfa_pen_thick; +solfa_pen_thick# = 1.75 stafflinethickness#; +define_blacker_pixels (solfa_pen_thick); + + +save solfa_base_notewidth; +solfa_base_notewidth# := black_notehead_width#; + +solfa_whole_width := whole_notehead_width# / black_notehead_width#; +solfa_half_width := half_notehead_width# / black_notehead_width#; +solfa_quarter_width := 1.0; + +def draw_do_head (expr width_factor, dir) = + save p_in, p_out; + save left_dist, right_dist; + path p_in, p_out; + pair left_dist, right_dist; + + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + + pickup pencircle scaled solfa_pen_thick; + + bot y1 = -d; + y1 = y2; + lft x1 = 0; + rt x2 = w; + top y3 = h; + x3 =.5 [x1, x2]; + + left_dist = (unitvector (z3 - z1) rotated 90) * 0.5 solfa_pen_thick; + right_dist = (unitvector (z2 - z3) rotated 90) * 0.5 solfa_pen_thick; + + p_in := (((z1 - left_dist) -- (z3 - left_dist)) intersectionpoint + (top z1 -- top z2)) + -- ((top z1 -- top z2) intersectionpoint + ((z2 - right_dist) -- (z3 - right_dist))) + -- (((z2 - right_dist) -- (z3 - right_dist)) intersectionpoint + ((z1 - left_dist) -- (z3 - left_dist))) + -- cycle; + + p_out := bot z1 + -- bot z2{right} + .. rt z2{up} + .. (z2 + right_dist){z3 - z2} + -- (z3 + right_dist){z3 - z2} + .. top z3{left} + .. (z3 + left_dist){z1 - z3} + -- (z1 + left_dist){z1 - z3} + .. lft z1{down} + .. {right}cycle; + + + labels (1, 2, 3); + + charwx := charwd; + charwy := -chardp + 0.5 stafflinethickness#; + if dir = -1: + charwy := -charwy; + fi; +enddef; + + +fet_beginchar ("Whole dohead", "s0do"); + draw_do_head (solfa_whole_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half dohead", "d1do"); + draw_do_head (solfa_half_width, -1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half dohead", "u1do"); + draw_do_head (solfa_half_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Quart dohead", "d2do"); + draw_do_head (solfa_quarter_width, -1); + fill p_out; +fet_endchar; + + +fet_beginchar ("Quart dohead", "u2do"); + draw_do_head (solfa_quarter_width, 1); + fill p_out; +fet_endchar; + + +% +% re - flat top, curved bottom: +% (0,h/2) {dir -90} .. (w/2,-h/2) .. {dir 90} (w,h/2) -- cycle; +% (broader along the base and with more vertical sides for half and +% whole notes) +% stem attachment: h/2 +% + +def draw_re_head (expr width_factor, dir) = + save p_in, p_out; + path p_in, p_out; + + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + + pickup pencircle scaled solfa_pen_thick; + + save curve_start; + curve_start = 0.7; + lft x1 = 0; + y1 = y5; + x1 = x2; + y2 = curve_start [y3, y1]; + bot y3 = -d; + x3 = .5 [x2, x4]; + rt x4 = w; + y4 = y2; + top y5 = h; + x5 = x4; + + labels (range 1 thru 5); + + p_in := (z1 + 0.5 solfa_pen_thick * (1, -1)) + -- rt z2{down} + .. top z3 + .. lft z4{up} + -- (z5 + 0.5 solfa_pen_thick * (-1, -1)) + -- cycle; + + p_out := lft z1 + -- lft z2{down} + .. bot z3 + .. rt z4{up} + -- rt z5{up} + .. top z5{left} + -- top z1{left} + .. {down}cycle; + + charwx := charwd; + charwy := curve_start [-chardp, charht]; + + if dir = -1: + charwy := -charwy; + fi; +enddef; + + +fet_beginchar ("Whole rehead", "s0re"); + draw_re_head (solfa_whole_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half up rehead", "u1re"); + draw_re_head (solfa_half_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half down rehead", "d1re"); + draw_re_head (solfa_half_width, -1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Quart rehead", "u2re"); + draw_re_head (solfa_quarter_width, 1); + fill p_out; +fet_endchar; + + +fet_beginchar ("Quart rehead", "d2re"); + draw_re_head (solfa_quarter_width, -1); + fill p_out; +fet_endchar; + + +def draw_mi_head (expr width_factor) = + save path_out, path_in; + save ne_dist, se_dist, ne, se; + path path_out, path_in; + pair ne_dist, se_dist, ne, se; + + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + + pickup pencircle scaled solfa_pen_thick; + + lft x1 = 0; + y1 = 0; + bot y2 = -d; + x2 = .5 [x1, x3]; + rt x3 = w; + x4 = x2; + y3 = y1; + top y4 = h; + + z6 - z5 = whatever * (z2 - z1); + z8 - z7 = whatever * (z2 - z1); + z8 - z5 = whatever * (z4 - z1); + z6 - z7 = whatever * (z4 - z1); + + ne = unitvector (z4 - z1); + se = unitvector (z1 - z2); + + ne_dist = (ne rotated 90) * 0.5 solfa_pen_thick; + se_dist = (se rotated 90) * 0.5 solfa_pen_thick; + + z5 = whatever [z1, z4] - ne_dist; + z5 = whatever [z1, z2] - 1.5 se_dist; + + z5 - z1 = -(z7 - z3); + + labels (range 1 thru 8); + + path_in := z5 + -- z6 + -- z7 + -- z8 + -- cycle; + + path_out := lft z1 + .. (z1 + se_dist){-se} + -- (z2 + se_dist){-se} + .. bot z2 + .. (z2 - ne_dist){ne} + -- (z3 - ne_dist){ne} + .. rt z3 + .. (z3 - se_dist){se} + -- (z4 - se_dist){se} + .. top z4 + .. (z4 + ne_dist){-ne} + -- (z1 + ne_dist){-ne} + .. cycle; +enddef; + + +fet_beginchar ("Whole mihead", "s0mi"); + draw_mi_head (solfa_whole_width); + fill path_out; + unfill path_in; +fet_endchar; + + +fet_beginchar ("Half mihead", "s1mi"); + draw_mi_head (solfa_quarter_width); + fill path_out; + unfill path_in; +fet_endchar; + + +fet_beginchar ("Quart mihead", "s2mi"); + draw_mi_head (solfa_quarter_width); + fill path_out; +fet_endchar; + + +def draw_fa_head (expr width_factor) = + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + + save p_down_in, p_down_out, p_up_in, p_up_out, nw_dist, nw; + path p_down_in, p_down_out, p_up_in, p_up_out; + pair nw_dist, nw; + + pickup pencircle scaled solfa_pen_thick; + + lft x1 = 0; + top y1 = h; + + rt x2 = w; + y2 = y1; + bot y3 = -d; + x3 = x2; + + y4 = y3; + x4 = x1; + + labels (1, 2, 3, 4); + + nw = unitvector (z1 - z3); + nw_dist = (nw rotated 90) * 0.5 solfa_pen_thick; + + p_up_in := (((z1 - nw_dist) -- (z3 - nw_dist)) intersectionpoint + (bot z1 -- bot z2)) + -- (((z1 - nw_dist) -- (z3 - nw_dist)) intersectionpoint + (lft z3 -- lft z2)) + -- (z2 + 0.5 solfa_pen_thick * (-1, -1)) + -- cycle; + + p_up_out := lft z1{down} + .. (z1 + nw_dist){-nw} + -- (z3 + nw_dist){-nw} + .. bot z3{right} + .. rt z3{up} + -- rt z2{up} + .. top z2{left} + -- top z1{left} + .. {down}cycle; + + p_down_in := p_up_in rotated 180 shifted (w, 0); + p_down_out := p_up_out rotated 180 shifted (w, 0); + + charwy := 0.0; + charwx := charwd; +enddef; + + +fet_beginchar ("Whole fa up head", "u0fa"); + draw_fa_head (solfa_whole_width); + fill p_up_out; + unfill p_up_in; +fet_endchar; + + +fet_beginchar ("Whole fa down head", "d0fa"); + draw_fa_head (solfa_whole_width); + fill p_down_out; + unfill p_down_in; +fet_endchar; + + +fet_beginchar ("half fa up head", "u1fa"); + draw_fa_head (solfa_half_width); + fill p_up_out; + unfill p_up_in; +fet_endchar; + + +fet_beginchar ("Half fa down head", "d1fa"); + draw_fa_head (solfa_half_width); + fill p_down_out; + unfill p_down_in; +fet_endchar; + + +fet_beginchar ("Quarter fa up head", "u2fa"); + draw_fa_head (solfa_quarter_width); + fill p_up_out; +fet_endchar; + + +fet_beginchar ("Quarter fa down head", "d2fa"); + draw_fa_head (solfa_quarter_width); + fill p_down_out; +fet_endchar; + + +def draw_la_head (expr width_factor) = + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + save p_in, p_out; + path p_in, p_out; + + pickup pencircle scaled solfa_pen_thick; + + lft x1 = 0; + top y1 = h; + + rt x2 = w; + y2 = y1; + bot y3 = -d; + x3 = x2; + + y4 = y3; + x4 = x1; + + labels (range 1 thru 4); + + p_in := (z1 + 0.5 solfa_pen_thick * (1, -1)) + -- (z2 + 0.5 solfa_pen_thick * (-1, -1)) + -- (z3 + 0.5 solfa_pen_thick * (-1, 1)) + -- (z4 + 0.5 solfa_pen_thick * (1, 1)) + -- cycle; + + p_out := top z1 + -- top z2{right} + .. rt z2{down} + -- rt z3{down} + .. bot z3{left} + -- bot z4{left} + .. lft z4{up} + -- lft z1{up} + .. cycle; +enddef; + + +fet_beginchar ("Whole lahead", "s0la"); + draw_la_head (solfa_whole_width); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half lahead", "s1la"); + draw_la_head (solfa_half_width); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Quart lahead", "s2la"); + draw_la_head (solfa_quarter_width); + fill p_out; +fet_endchar; + + +def draw_ti_head (expr width_factor, dir) = + set_char_box (0, width_factor * solfa_base_notewidth#, + 0.5 solfa_noteheight#, 0.5 solfa_noteheight#); + save p_in, p_out, p_top; + save nw_dist, sw_dist, nw, sw; + path p_in, p_out, p_top; + pair nw_dist, sw_dist, nw, sw; + save cone_height; + cone_height = 0.64; + + pickup pencircle scaled solfa_pen_thick; + + x1 = .5 [x2, x4]; + bot y1 = -d; + lft x2 = 0; + y2 = cone_height [y1, y3]; + rt x4 = w; + y4 = y2; + x3 = x1; + top y3 = h; + + labels (range 1 thru 4); + + nw = unitvector (z2 - z1); + sw = unitvector (z1 - z4); + + nw_dist = (nw rotated 90) * 0.5 solfa_pen_thick; + sw_dist = (sw rotated 90) * 0.5 solfa_pen_thick; + + p_top := (z2 - sw_dist) + .. (top z3){right} + .. (z4 - nw_dist); + + p_in := (((z1 - nw_dist) -- (z2 - nw_dist)) intersectionpoint + ((z1 - sw_dist) -- (z4 - sw_dist))) + -- (((z1 - nw_dist) -- (z2 - nw_dist)) intersectionpoint + ((z2 + sw_dist) .. {right}(bot z3))) + .. bot z3 + .. (((bot z3){right} .. (z4 + nw_dist)) intersectionpoint + ((z1 - sw_dist) -- (z4 - sw_dist))) + -- cycle; + + p_out := bot z1 + .. (z1 + nw_dist) + -- (z2 + nw_dist) + .. lft z2 + .. (z2 - sw_dist){direction 0 of p_top} + & p_top + & {direction infinity of p_top}(z4 - nw_dist) + .. rt z4 + .. (z4 + sw_dist) + -- (z1 + sw_dist) + .. cycle; + + charwx := charwd; + charwy := cone_height [-chardp, charht]; + if dir = -1: + charwy := -charwy; + fi; +enddef; + + +fet_beginchar ("Whole up tihead", "s0ti"); + draw_ti_head (solfa_whole_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half up tihead", "u1ti"); + draw_ti_head (solfa_half_width, 1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Half down tihead", "d1ti"); + draw_ti_head (solfa_half_width, -1); + fill p_out; + unfill p_in; +fet_endchar; + + +fet_beginchar ("Quart up tihead", "u2ti"); + draw_ti_head (solfa_quarter_width, 1); + fill p_out; +fet_endchar; + + +fet_beginchar ("Quart down tihead", "d2ti"); + draw_ti_head (solfa_quarter_width, -1); + fill p_out; +fet_endchar; + + +fet_endgroup ("noteheads"); + + +% +% we derive black_notehead_width# from the quarter head, +% so we have to define black_notehead_width (pixel qty) +% after the black_notehead_width# itself. +% +% Let's keep it outside the group as well. +% + +define_pixels (black_notehead_width); diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-a.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-a.mf new file mode 100644 index 00000000..9d8a9d83 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-a.mf @@ -0,0 +1,11 @@ +% +% feta-braces-a.mf -- 256 smallest braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 0; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-b.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-b.mf new file mode 100644 index 00000000..e74606dc --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-b.mf @@ -0,0 +1,11 @@ +% +% feta-braces-b.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 1; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-c.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-c.mf new file mode 100644 index 00000000..06a273ed --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-c.mf @@ -0,0 +1,11 @@ +% +% feta-braces-c.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 2; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-d.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-d.mf new file mode 100644 index 00000000..d926a595 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-d.mf @@ -0,0 +1,11 @@ +% +% feta-braces-d.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 3; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-e.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-e.mf new file mode 100644 index 00000000..ed89fc5a --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-e.mf @@ -0,0 +1,11 @@ +% +% feta-braces-e.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 4; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-f.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-f.mf new file mode 100644 index 00000000..4a96744e --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-f.mf @@ -0,0 +1,11 @@ +% +% feta-braces-f.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 5; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-g.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-g.mf new file mode 100644 index 00000000..3a12239c --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-g.mf @@ -0,0 +1,11 @@ +% +% feta-braces-g.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 6; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-h.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-h.mf new file mode 100644 index 00000000..9d4988e7 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-h.mf @@ -0,0 +1,11 @@ +% +% feta-braces-h.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 7; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-braces-i.mf b/muse2/share/scoreglyphs/feta-original/feta-braces-i.mf new file mode 100644 index 00000000..7089e60c --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-braces-i.mf @@ -0,0 +1,11 @@ +% +% feta-braces-i.mf -- next 256 braces +% +% source file of the Feta (Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + +font_count := 8; +input feta-beugel; +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-din-code.mf b/muse2/share/scoreglyphs/feta-original/feta-din-code.mf new file mode 100644 index 00000000..809227de --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-din-code.mf @@ -0,0 +1,791 @@ +% feta-din-code.mf -- implement dynamic signs +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org> + + +ex# := (dynamic_design_size / 2.4) * pt#; +descender# := 0.5 ex#; +ascender# := 0.72 ex#; +staffspace# := 1.75 / 2.0 * ex#; +horizontal_space# := .66 ex#; + +font_x_height ex#; +font_normal_space horizontal_space#; + +define_pixels (staffspace, linethickness, ex, descender, ascender); + + +% +% TODO: blot diameter should be fixed, not scalable. +% + +save serif_thick, med_thick, bottom_blot; + +serif_thick# = 1.1 linethickness#; +define_blacker_pixels (serif_thick); + +med_thick = round (1.5 linethickness); +bottom_blot = 1.3 serif_thick; + + +code := 32; + +fet_beginchar ("Space", "space"); + set_char_box (0, horizontal_space#, 0, ex#); +fet_endchar; + + +% +% Couldn't find many z examples. This one is losely inspired +% by a sfz from Mueller Etuden fuer Horn (Edition Hofmeister). +% + +code := 121; + +fet_beginchar ("dynamic z", "z"); + save thin_thick, top_narrow, over_shoot; + save bot_thick; + + set_char_box (0, .98 ex#, 0, 0.9 ex#); + + thin_thick = serif_thick; + top_narrow = thin_thick; + top_overshoot = .8 serif_thick; + top_thick = .3 h; + bot_thick = .2 ex; + bot_overshoot = serif_thick; + + x0 = top_narrow; + y0 = .9 [y1r, y1l]; + + penpos1 (top_thick, 80); + y1l = .72 h; + x1r = .34 ex; + + x2 = .66 ex; + y2 = y1r - top_overshoot; + + y3 = h - .7 thin_thick; + x3 = w - .6 top_narrow - .5 thin_thick; + y4 = .5 thin_thick; + x4 = .5 thin_thick; + + penpos3 (thin_thick, angle (z3 - z4) + 90); + penpos4 (thin_thick, angle (z3 - z4) + 90); + + penpos5 (bot_thick, 70); + x5l =.25 ex; + y5l = .4 bot_overshoot; + + penpos6 (3/2 bot_thick, 70); + y6l = -bot_overshoot; + x6 = w - 3 top_narrow; + + x7 = w; + y7 = .82 [y8r, y6r]; + + penpos8 (thin_thick, 20); + x8r = w - .35 top_narrow; + y8r = .45 h; + + penlabels (range 0 thru 8); + +% pickup pencircle scaled 1; + +% draw + fill z0{down} + .. z1l{dir (10)} + .. simple_serif (z3l, z3r, 90) + .. z2{left} + .. z1r{left} + ..tension 1.2.. cycle; + +% draw + fill z3l + -- z3r + -- z4r + -- z4l + -- cycle; + +% draw + fill simple_serif (z4r, z4l, 90) + .. z5l{right} + .. z6l{right} + .. z7{up} + .. simple_serif (z8r, z8l, 90) + .. z6r{left} + .. z5r{left} + .. cycle; +fet_endchar; + + +% forte f, grabbed from Ed Breitkopf Mozart horn concerto 3. +% +% NOTES: +% +% * the bulbs are open +% +% * blotting around the serif +% +% TODO: insert blots around the serif +% + +slant_angle = 20; +code := 101; + +fet_beginchar ("dynamic f", "f"); + save left_angle, right_angle; + save serif_length, serif_eccentricity; + save f_thick; + save bulb_thick, bulb_diam, fill_up; + save slant; + save p; + path p; + + set_char_box (0, 1.1 ex#, descender#, ex# + ascender#); + + bulb_diam = 7.5 / 40 ex; + bulb_thick = 8.5 / 40 ex; + fill_up = 1.5 serif_thick; + left_angle = slant_angle - 6; + right_angle = slant_angle - 3; + f_thick = 7/16 ex; + serif_length = 0.96 ex; + serif_eccentricity = 0.01 ex; + + % z1 is the `base point' + z1 = (0.2 ex, -serif_thick); + + penpos2 (f_thick, 0); + y2 = y1 + ex; + z2l = z1 + whatever * dir (90 - left_angle); + + penpos3 (med_thick, -90); + y3l = y1 + ex + ascender; + x3l = x1 + ex; + + penpos4 (bulb_thick, -20); + z3r = whatever [z4r, z4l]; + + x4l - x3l = 1/10 ex; + + penpos5 (bulb_thick, -45); + x5r = 0.1 [x4l, x4r]; + y5l = y4l - bulb_diam; + + z6 = z2r + whatever * dir (90 - right_angle); + y6 = y1 + 3/8 ex; + + penpos7 (med_thick, -90); + x7 = x1 - 1/4 ex; + y7r = y1 -descender; + + penpos8 (bulb_thick, 160); + x8l = x7l - 1/10 ex; + + z7l = whatever [z8r, z8l]; + + penpos9 (bulb_thick, 135); + x9r = 0.1 [x8l, x8r]; + y9l = y8l + bulb_diam; + + labels (1, 6, 9); + penlabels (2, 3, 4, 5, 7, 8, 9); + +% pickup pencircle scaled 1; + +% draw + fill z1 + -- z2l{z2l - z1} + ..tension 1.1.. z3l{right} + .. z4r{down} + .. z5r{left} + .. z5l{up} + ..tension 0.8.. z4l{up} + .. z3r{left} + ..tension 1.1.. z2r{z6 - z2r} + -- z6{z6 - z2r} + ..tension 1.25.. z7r{left} + .. z8r{up} + .. z9r{right} + .. z9l{down} + ..tension 0.8.. z8l{down} + .. z7l{right} + .. {z2l - z1}cycle; + + x13 - x14 = serif_length; + y13 = y14; + y14 = y2; + 0.5 [x13, x14] = x2 + serif_eccentricity; + + draw_rounded_block (z14 - (0, 0.7 serif_thick), + z13 + (0, 0.7 serif_thick), + 1.4 serif_thick); + + labels (13, 14); +fet_endchar; + + +% +% Notes: +% +% - The `s' is trapezoidal (i.e., narrower at the top). +% +% - The white space is differently shaped at the top (the bulb's inner +% curve is filled up). +% +% - Less heavy than the `f' and `p' signs. +% + +code := 114; + +fet_beginchar ("dynamic s", "s"); + save left_angle, right_angle; + save s_thick, s_thin; + save bulb_diam, bulb_len; + save over_shoot; + save base_point; + pair base_point; + + set_char_box (0, 17/24 ex#, 0, ex#); + + over_shoot = 0; % .2 serif_thick; + bulb_diam = 11/70 ex; + bulb_len = 1.0 bulb_diam; + left_angle = slant_angle - 2; + right_angle = slant_angle - 11; + s_thick = 16/70 ex; + s_thin = serif_thick; + + base_point = (0, 0); + + penpos1 (bulb_diam, -45); + z1 = 0.35 [z2l, z2r] + bulb_len * dir (45); + + penpos2 (bulb_diam, -25); + y2l = 0.845 [y7r, y3r]; + z2l = base_point + whatever * dir (90 - left_angle); + + penpos3 (s_thin, 100); + x3l = 1/2 w; + y3l = ypart base_point - over_shoot; + + penpos4 (s_thick, 25); + y4l = y1r; + z4r = base_point + (w, 0) + whatever * dir (90 - right_angle); + + penpos5 (s_thick, 40); + z5 = z3l + whatever * dir (90 - right_angle); + y5 = 0.48 [y7r, y3r]; + + penpos6 (s_thick, 25); + z6l = base_point + whatever * dir (90 - left_angle); + y6r = y9l; + + penpos7 (.9 s_thin, 110); + z7l = 0.45 [z6r, z8l] + whatever * dir (90 - left_angle); + y7r = h + over_shoot; + + penpos8 (.9 bulb_diam, -25); + z8 = .6 [z4l, z4r] + whatever * dir (90 - right_angle); + y8r = 0.23 [y7r, y3r]; + + penpos9 (.9 bulb_diam, -45); + z9 = .4 [z8r, z8l] + .9 bulb_len * dir (-135); + + penlabels (range 1 thru 9); + +% pickup pencircle scaled 1; + +% draw + fill z2l{down} + .. z3l{right} + .. z4r{up} + .. z5r + .. z6r{up} + .. z7l{right} + % .. z8l{down} + .. z9l{dir (-125)} + .. z9r{right} + .. z7r{left} + .. z6l{down} + .. z5l + .. z4l{down} + .. z3r{left} + .. z2r{up} + .. z1r{up} + .. z1l{left} + .. cycle; +fet_endchar; + + +% for `p' and `m' + +save slant; +slant := ypart (dir (slant_angle)); + + +% +% Piano `p', grabbed from Ed Breitkopf Mozart horn concerto 3. +% +% Notes: +% +% * There is no dishing in the serif (but we do it anyway). +% +% * The cheek is a little fatter than the stem. +% +% * The slant is extreme: 20 degrees. +% +% * The twiddle (what's-it-called) is a slightly darker than the serif. +% +% * The hole in the cheek has a straight right side. +% +% * Corners are filled up. +% + +code := 111; + +fet_beginchar ("dynamic p", "p") + % TODO: w really is 13/12 ex + % but should do kerning + + save twiddle_thick, stem_thick, cheek_thick, cheek_width; + save fill_up, straigh_len; + save serif, dishing_angle, p, tmp; + save cheek_medium, left_serif_protrude, right_serif_protrude; + save lower_overshoot; + save blot_t, corner_t; + path serif, p; + pair tmp, updir; + + set_char_box (0, 15/12 ex#, descender#, 1.0 ex#); + + twiddle_thick = med_thick; + cheek_medium = 1/6 ex; + + dishing_angle = 5; + fill_up = 1.5 serif_thick; + straigh_len = 0.5 ex; + lower_overshoot = .3 serif_thick; + + stem_thick = 2/6 ex; + cheek_thick = 13/32 ex; + cheek_width = 0.72 ex; + left_serif_protrude = 18/60 ex; + right_serif_protrude = 15/60 ex; + + currenttransform := currenttransform slanted slant; + + penpos1 (twiddle_thick, -slant - 5); + penpos2 (cheek_medium, 90 - slant); + penpos3 (cheek_medium, 90 - slant); + + x4r - x4l = cheek_thick; + + penpos4 (whatever, 0); + penpos5 (whatever, -38); + penpos6 (stem_thick, 0); + penpos17 (straigh_len, 90 - slant); + + whatever [z17l, z17r] = z4l; + y17 = 7/16 ex; + x6l = 0; + y6l = -descender + serif_thick / 2; + z1l = z6l - whatever * dir (110); + y1r = 0.5 ex; + y2r = ex; + z7 = whatever * up + z6l; + y7 = 43/60 ex; + z2l = whatever * up + 0.3 [z7, z1r]; + y8 = 0.9 [y7, y2l]; + z8 = 2/3 [z6l, z6r] + whatever * up; + y3r = ex; + z3l = 0.58 [(stem_thick, -descender), + (stem_thick + cheek_width - cheek_thick, -descender)] + + whatever * up; + y4r = .38 ex; + z4r = whatever * up + (stem_thick + cheek_width, -descender); + z5l = whatever * up + z3l; + y5r = -lower_overshoot; + y5l = y5r + cheek_medium * ypart dir (55); + z9 = z6r + whatever * up; + y9 = .2 [y5l, y5r]; + + p := z2r{right} + .. {dir (-60)}z8{dir 60} + .. z3r{right} + .. z4r{down} + ..tension 1.1.. z5r{left} + .. {curl 1}z9 + -- z6r + -- z6l + -- z7{up} + .. z2l{left} + ..tension 1.2.. simple_serif (z1r, z1l, -90) + .. cycle; + + blot_t := 0.13; + corner_t := xpart (p intersectiontimes z9); + +% pickup pencircle scaled 1; + +% draw + fill subpath (0, corner_t - 2 blot_t) of p + .. subpath (corner_t + blot_t, length p) of p + .. cycle; + + y12 = 0.5 ex; + z12 = z6r + whatever * up; + + unfill z17l + ..tension 1.5.. z17r + .. z3l{left} + ..tension 1.05.. z12{down} + ..tension 1.05.. z5l{right} + .. cycle; + + penlabels (1, 2, 3, 4, 5, 6, 17); + labels (7, 8, 9); + + pickup pencircle scaled serif_thick; + + lft x11 = -left_serif_protrude; + rt x10 = stem_thick + right_serif_protrude; + bot y10 = bot y11 = -descender; + + z15 = z6l + up * fill_up; + z16 = z6r + up * 1.2 fill_up; + + % Since pens are not affected by currenttransform we directly + % transform the necessary points, then simulating the pen with + % an outline while using the identity transformation. + + forsuffixes $ = 7, 10, 11, 15, 16: + tmp := z$ transformed currenttransform; + x$ := xpart tmp; + y$ := ypart tmp; + endfor; + + currenttransform := identity; + + updir = z7 - z15; + + serif := simple_serif (z10, z11, dishing_angle); + + penpos10 (serif_thick, -dishing_angle - 90); + penpos11 (serif_thick, dishing_angle - 90); + penpos13 (serif_thick, angle (direction 0.05 of serif) + 90); + penpos14 (serif_thick, angle (direction 0.85 of serif) + 90); + + z13 = point 0.05 of serif; + z14 = point 0.85 of serif; + + penlabels (10, 11, 13, 14); + labels (15, 16); + +% draw + fill z15{-updir} + .. z14l{direction 0.85 of serif} + .. z11l{-dir (dishing_angle)} + .. z11r{dir (dishing_angle)} + .. z14r{-direction 0.85 of serif} + .. z13r{-direction 0.05 of serif} + .. z10r{dir (-dishing_angle)} + .. z10l{-dir (-dishing_angle)} + .. z13l{direction 0.05 of serif} + .. z16{updir} + -- cycle; +fet_endchar; + + +% +% NOTES: +% +% * Right stem is fatter and more straight than the left two stems. +% +% * The twiddle at the left is similar to the `p' twiddle. +% +% * The bottoms of the stems are blotted. +% +% +% This is cut & paste programming. Somehow three `i' shapes in two +% characters (`p' and `m') -- doesn't seem worth the trouble of writing +% a macro. +% + +code := 108; + +fet_beginchar ("dynamic m", "m"); + save i_thick, i_angle, i_twiddle_thick; + save i_twiddle_start_angle, i_twiddle_start_y; + save i_twiddle_end_angle, i_left_space; + save idir, center, right_ending; + save overshoot; + save p; + pair center, idir, right_ending; + path p; + + set_char_box (0, 1.5 ex#, 0, 1.0 ex#); + + % should share code with p for twiddle. + + overshoot = .25 serif_thick; + i_thick := 21/80 ex; + i_twiddle_thick = 1.2 serif_thick; + i_twiddle_start_y = 8/16 ex; + i_twiddle_start_angle = 0; + i_twiddle_end_angle := 35; + + center = (0, 0); + + currenttransform := currenttransform slanted slant; + + i_angle := 0; + idir := dir (90 - i_angle); + i_left_space = 16/80 ex; + + penpos1 (i_twiddle_thick, -i_twiddle_start_angle); + y1 = i_twiddle_start_y; + z1r = center - (i_left_space, 0) + whatever * idir; + + y2l = ex + overshoot; + z2l = .08 [z3l, z3r] + whatever * idir; + z2r = 5/8 [z1r, z3l] + whatever * idir; + y2r = y5l + 1/9 ex; + z2 = 1/2 [z2l, z2r]; + + penpos3 (i_thick, 0); + y3 = 0.5 bottom_blot + ypart center; + z3l = center + whatever * idir; + + penpos4 (i_thick - bottom_blot, 0); + y4 = ypart center; + z4 - z3 = whatever * idir; + + penpos5 (i_thick, 0); + z5 = z4 + whatever * idir; + y5 = 55/80 ex; + + fill simple_serif (z1l, z1r, 90) + ..tension 1.2.. z2r{right} + .. z5l{z3 - z5} + -- z3l{z3 - z5} + .. z4l{right} + -- z4r{right} + .. z3r{z5 - z3} + -- z5r{z5 - z3} + ..tension 1.2.. z2l{left} + .. cycle; + + right_ending := z5r; + penlabels (1, 2, 3, 4, 5); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + clearxy; + + i_angle := -3.2; + idir := dir (90 - i_angle); + i_left_space := 14/80 ex; + + penpos1 (serif_thick, -i_twiddle_start_angle); + z1r = right_ending; + + y2l = ex+ overshoot; + z2l = .08 [z3l, z3r] + whatever * idir; + z2r = 5/8 [z1r, z3l] + whatever * idir; + y2r = y5l + 1/9 ex; + z2 = 1/2 [z2l, z2r]; + + penpos3 (i_thick, 0); + y3 = 0.5 bottom_blot + ypart center; + z3l = z5l + whatever * idir; + + penpos4 (i_thick - bottom_blot, 0); + y4 = ypart center; + z4 - z3 = whatever * idir; + + penpos5 (i_thick, 0); + z5l = right_ending + (i_left_space, 0); + + fill simple_serif (z1l, z1r, 90) + ..tension 1.05.. z2r{right} + .. z5l{z3 - z5} + -- z3l + .. z4l{right} + -- z4r{right} + .. z3r{z5 - z3} + -- z5r{z5 - z3} + ..tension 1.2.. z2l{left} + .. cycle; + + right_ending := z5r; + penlabels (1, 2, 3, 4, 5); + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + clearxy; + + i_thick := 23/80 ex; + i_angle := -6; + idir := dir (90 - i_angle); + i_left_space := 14/80 ex; + + penpos1 (serif_thick, -i_twiddle_start_angle); + z1r = right_ending; + + y2l = ex + overshoot; + z2l = .08 [z3l, z3r] + whatever * idir; + z2r = 5/8 [z1r, z3l] + whatever * idir; + y2r = y5l + 1/9 ex; + z2 = 1/2 [z2l, z2r]; + + penpos3 (whatever, 20); + y3l = 1/8 ex + ypart center; + z3l = z7l + whatever * idir; + z3r = z7r + whatever * idir; + + penpos5 (whatever, 10); + z5l = right_ending + (i_left_space, 0); + z5r = z7r + whatever * idir; + + penpos6 (serif_thick, -i_twiddle_end_angle); + y6l = 23/80 ex + ypart center; + z6l = 1.6 [z3l, z3r] + whatever * idir; + + penpos7 (i_thick, 0); + y7 = 0; + z7l = z5l + whatever * idir; + + z8 = z7 - (0, overshoot); + + fill simple_serif (z1l, z1r, 90) + ..tension 1.05.. z2r{right} + .. z5l{z3 - z5} + -- z3l{z3 - z5} + .. z8{right} + .. simple_serif (z6r, z6l, 90) + ..tension 0.85.. z3r{z5 - z3} + -- z5r{z5 - z3} + ..tension 1.2.. z2l{left} + .. cycle; + + penlabels (range 1 thru 8); +fet_endchar; + + +code := 113; + +fet_beginchar ("dynamic r", "r"); + save base_point, stem_thick, bulb_diam; + save twiddle_thick, attach_len, overshoot, taille; + pair base_point; + + set_char_box (0, .75 ex#, 0, ex#); + + stem_thick =.26 ex; + bulb_diam = .30 ex; + twiddle_thick = 1.1 serif_thick; + overshoot = .5 serif_thick; + taille = -0.3 serif_thick; + attach_len + bulb_diam / 2 + stem_thick = w; + + + base_point = (0, 0); + + currenttransform := identity slanted ypart (dir (15)); + + penpos1 (stem_thick, 0); + x1l = 0; + y1l = .5 bottom_blot; + + penpos2 (stem_thick, 0); + x2l = x1l; + y2l - y1l = 36/47 ex; + + penpos3 (twiddle_thick, -20); + x3r = x2l - .2 ex; + y3 = .77 ex; + + x4l = -0.1 [x1l, x1r]; + y4l = ex + overshoot; + x4r = 0.62 [x3r, x2l]; + y4r = 0.5 [y4l, y2l]; + + penpos5 (whatever, -74); + y5l - y5r = bulb_diam; + y5l = ex + overshoot; + x5 = x2r + attach_len; + + penpos6 (bulb_diam, 0); + z6 = z5; + +% z7 = z6l + taille * dir (180); + z7 = z6 + .4 * bulb_diam * dir (-125); + + z8 = 9/10 [z1r, z2r]; + + x9 = 0.15 [x1r, x1l]; + y9 = y4l - .12 ex; + + penpos10 (stem_thick - bottom_blot, 0); + x10 = x1; + y10 = 0; + +% pickup pencircle scaled 1; + +% draw + fill z1r{down} + .. z10r{left} + -- z10l{left} + .. z1l{up} + -- z2l{up} + .. z4r{left} + ..tension 1.2.. {down}simple_serif (z3r, z3l,-90){up} + ..tension 0.95.. z4l + .. {curl 1}z9{curl 1} + .. z5l + .. z6r{dir (-80)} + .. z5r{left} + .. z7 + .. z6l + ..tension 1.2.. z8{down} + -- cycle; + + penlabels (range 1 thru 10); +fet_endchar; + + +%%% KERNING + +ligtable "m": + "p" kern 0.2 ex#, + "f" kern -0.1 ex#; + +ligtable "f": + "f" kern -0.13 ex#; + +ligtable "r": + "f" kern 0.1 ex#; + + +%% notes from old dyn code. + +% `f' obviously has a _lot_ bigger slant than `p' (see Wanske p.239). +% However; perhaps we need two f symbols: +% - a super-slanted one used in `f', `mf', `sfz', `sf' +% - a more normal-slanted in `ff', `fff', `fp', `fp' (see Wanske p.241) +% +% Looking at professionally typeset music reveals that typesetters +% are somewhat unsure about slanting in `mf', `fp', `sfz' +% +% `f' and `p' (in any combination) are a lot (factor two) fatter than +% `s', `m', and `z'. Sometimes the `m' and `z' are a bit fatter than +% `s'. +% +% Chester, Breitkopf suggest smaller sizes of these other glyphs, +% using the x-height as reference point. diff --git a/muse2/share/scoreglyphs/feta-original/feta-eindelijk.mf b/muse2/share/scoreglyphs/feta-original/feta-eindelijk.mf new file mode 100644 index 00000000..de97f186 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-eindelijk.mf @@ -0,0 +1,593 @@ +% feta-eindelijk.mf -- implement rest symbols -*-Fundamental-*- +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org> + +fet_begingroup ("rests"); + +save block_rest_y, block_rest_x; +save breve_rest_y, breve_rest_x; + +breve_rest_y# = staff_space#; +breve_rest_x# = 3/5 staff_space#; +block_rest_y# = 5/8 staff_space#; +block_rest_x# = 3/2 staff_space#; + +define_whole_pixels (block_rest_y, block_rest_x); +define_whole_pixels (breve_rest_y, breve_rest_x); + + +def block_rest = + draw_block ((0, 0), (block_rest_x, block_rest_y)); +enddef; + + +fet_beginchar ("whole rest", "0"); + set_char_box (0, block_rest_x#, + block_rest_y#, 0); + + block_rest; + currentpicture := currentpicture + shifted (0, -block_rest_y + feta_space_shift); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("half rest", "1"); + set_char_box (0, block_rest_x#, 0, block_rest_y#); + + block_rest; + + draw_staff (-2, 2, 0); +fet_endchar; + + +% +% should use ledgerline thickness? +% +fet_beginchar ("whole rest (outside staff)", "0o"); + set_char_box (0, block_rest_x#, + block_rest_y#, ledgerlinethickness# / 2); + + block_rest; + currentpicture := currentpicture shifted (0, -block_rest_y); + + pickup pencircle scaled ledgerlinethickness; + + y5 = y6 = 0; + lft x5 = -b - block_rest_y; + rt x6 = w + block_rest_y; + draw_gridline (z5, z6, ledgerlinethickness_rounded); + + draw_staff (-2, 2, -3); +fet_endchar; + + +fet_beginchar ("half rest (outside staff)", "1o"); + set_char_box (0, block_rest_x#, + ledgerlinethickness# / 2, block_rest_y#); + + block_rest; + + pickup pencircle scaled ledgerlinethickness; + + y5 = y6 = 0; + lft x5 = -b - block_rest_y; + rt x6 = w + block_rest_y; + + draw_gridline (z5, z6, ledgerlinethickness_rounded); + + draw_staff (-2, 2, 3); +fet_endchar; + + +fet_beginchar ("maxima rest", "M3"); + set_char_box (0, 3 breve_rest_x#, breve_rest_y#, breve_rest_y#); + + draw_block ((0, -breve_rest_y + feta_shift), + (breve_rest_x, breve_rest_y)); + + addto currentpicture also currentpicture shifted (2 breve_rest_x, 0); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("longa rest", "M2"); + set_char_box (0, breve_rest_x#, breve_rest_y#, breve_rest_y#); + + draw_block ((0, -breve_rest_y + feta_shift), + (breve_rest_x, breve_rest_y)); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("breve rest", "M1"); + set_char_box (0, breve_rest_x#, 0, breve_rest_y#); + + draw_block ((0, 0), (breve_rest_x, breve_rest_y)); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Quarter rest", "2"); + save alpha, yshift, height; + save xcenter; + + yshift# := -1.25 staff_space#; + height# := 2.8125 staff_space#; + define_pixels (yshift, height); + + alpha := -50; + thick := 1/4 staff_space; + rthin := 1.25 linethickness; + xcenter := -0.1 staff_space; + rthick := 2 thick + rthin; + + set_char_box (0, 0.95 staff_space#, -yshift#, yshift# + height#); + + save ne, nw, se, sw; + pair ne, nw, se, sw; + + se = dir alpha; + ne = dir (alpha + 90); + nw = dir (alpha + 180); + sw = dir (alpha + 270); + + penpos1 (rthin, alpha + 90); + penpos2 (5/4 rthick, alpha); + penpos4 (5/4 rthick, alpha); + penpos5 (rthin, alpha + 90); + penpos3 (3/4 rthick, alpha); +% penpos6 (5/8 rthick, alpha); + penpos6 (2/3 rthick, alpha); + penpos7 (1/2 rthin, alpha + 90); + + z10 = z2l + 1/2 rthin * sw; +% z11 = z4l + 1/2 rthin * sw; + z11 = z4l + 1/2 rthin * sw + 1/2 rthin * se; + z12 = z4r + 1/2 rthin * ne; +% z13 = z2r + 1/2 rthin * ne; + z13 = z2r + 1/2 rthin * ne + 1/2 rthin * nw; + + y1r = h; + x1l = xcenter + 1/3 staff_space; + z2r = z1 + staff_space * se; + z3 = 1/2 [z2, z4]; + x4 = xcenter + 3/8 staff_space; + y4 = 0; + y4l := vround y4l; + z5 = round (z4l + 1.3 staff_space * se) + feta_offset; + x6l = x4l; + y6l = vround y4r; + x6r := hround x6r + xpart feta_offset; + y6r := vround y6r + ypart feta_offset; + x7 = hround (xcenter + 2/5 staff_space) + xpart feta_offset; + y7 = -d; + + save before, after; + path before, after; + before = z11{se} + .. {se}z5l; + after = z5r{nw} + ..tension1.4.. z6l; + (u, v) = before intersectiontimes after; + + fill z1l{se} + .. {se}z10 + .. z3l + .. subpath (0, u) of before + .. subpath (v, infinity) of after + ..tension1.4.. {se}z7l + .. z7r{nw} + ..tension1.4.. z6r + ..tension1.4.. {se}z5l + .. z5r{nw} + .. {nw}z12 + .. z3r + .. z13{nw} + .. {nw}z1r + .. cycle; + + penlabels (1, 2, 3, 4, 5, 6, 7); + penlabels (10, 11, 12, 13); + + draw_staff (-2, 2, 0); +fet_endchar; + + +% +% Notes about 8th rest: +% +% * 8th rest should be no wider than the black note head +% +% * The inside corner of the horizontal portion is usually a little blotted. +% +% * The top of the crook chops off the vertical brush +% +% * The crook widens a little +% +% * The bottom of the brush is slightly flat, as it has to align with +% stafflines if it is inside the staff. +% +% * The top of the brush usually is a little lower than the top of bulb. +% +% * The bulb can vary. Sometimes it is open (like in the clefs). Sometimes +% it is closed, or even a flare. +% + +% from an email to Rune Zedeler: +% +% +% For example, the 8th rest was vaguely based on a book with trumpet +% studies by Duhem, and by Baerenreiters cello suites. I included my +% findings in a comment in the mf file. One of the things that I tried +% to do was make the rest a little lighter and narrower than the black +% note head. I think this looks better in polyphonic music, when the +% rest is below a head from a different voice. +% + +save bulb_diam, thin, thick; + +bulb_diam# := 0.64 staff_space#; +thin# := 1.4 linethickness# - 0.02 staff_space#; +thick# := 2.2 linethickness#; + +crook_thin := 0.5 linethickness + 0.08 staff_space; +lower_brush := 1.5 linethickness; + +define_pixels (bulb_diam); +define_whole_blacker_pixels (thin, thick); + + +% +% PAT is a compact way to pass the brush shape to the routine. +% + +def draw_rest_bulb (expr ycenter, ycut, pat, stretch, show_labels) = +begingroup; + save x, y, pt, res; + + z1l = point 0 of pat; + z2l = point 1 of pat; + z2r = point 3 of pat; + z1r = point 4 of pat; + z1 = 0.5 [z1l, z1r]; + z2 = 0.5 [z2l, z2r]; + y10 = ycenter; + z10 = whatever [z2, z1] + left * bulb_diam * stretch; + + % this enforces similar bulb shapes for lower resolutions + x10 := hround x10; + + z3 = z10 + bulb_diam / 2.15 * dir (-72); + y3 := hround y3; + z5 = z10 + up * bulb_diam / 2 + right * linethickness / 3; + y5 := hround y5; + + z7 = 0.5 [z4, z5] + crook_thin * (0.45, 0.4) / 1.3; + x8 = hround (x10 - 0.4 bulb_diam); + y8 = y10 + 0.25 linethickness; + + z6 = whatever [z1l, z2l]; + z6 = z3 + whatever * dir (12); + + z4 = z3 + whatever * (z6 - z3) + + 1.1 crook_thin * (unitvector (z6 - z3) rotated 90); + x4 = x10 + bulb_diam * .62; + y4 := vround y4; + + (pt, whatever) = pat intersectiontimes ((0, ycut) -- (w, ycut)); + + path res; + res = point pt of pat {-direction pt of pat} + ..tension 2.. z4{left} + ..tension 0.9.. z7 + .. z5{left} + .. z8 + .. z3{right} + .. {curl 0.2}z6; + + if show_labels = 1: + labels (3, 4, 5, 6, 7, 8, 10); + fi; + +res +endgroup; +enddef; + + +def draw_eighth_rest (expr show_labels) = + save ycenter; + save pat, bulb; + path pat, bulb; + + set_char_box (0, 1.0 staff_space#, + 1.0 staff_space# + 0.5 linethickness#, + 0.5 staff_space# + bulb_diam# / 2); + + penpos1 (thick, 0); + penpos2 (thin, 10); + + y1 = -staff_space_rounded; + y2 = h - vround lower_brush; + x2r = w; + z2 = z1 + whatever * dir (72); + z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10); + y9 := vround y9; + + x1l := hround x1l; + x1r := hround x1r; + x1 := .5 [x1l, x1r]; + + if show_labels = 1: + penlabels (1, 2); + labels (9); + fi; + + pat = z1l + -- z2l + .. z9 + .. z2r + -- z1r + .. cycle; + bulb = draw_rest_bulb (0.5 staff_space, y2r, pat, 1.0, show_labels); + + fill simple_serif (z1l, z1r, 40) + -- z2r + .. z9 + .. bulb + -- z1l + .. cycle; + + draw_staff (-2, 2, 0); +enddef; + + +fet_beginchar ("Classical quarter rest", "2classical"); + draw_eighth_rest (0); + currentpicture := currentpicture xscaled -1 shifted (w, 0); +fet_endchar; + + +fet_beginchar ("8th rest", "3"); + draw_eighth_rest (1); +fet_endchar; + + +% +% TODO: the X dimensions of the rests are fucked up: +% they can collide with augmentation dots. +% + +fet_beginchar ("16th rest", "4"); + save ycenter; + save pat, bulb_a, bulb_b; + path pat, bulb_a, bulb_b; + + set_char_box (0, 1.2 staff_space#, + 2.0 staff_space# + 0.5 linethickness#, + 0.5 staff_space# + bulb_diam# / 2); + + penpos1 (thick, 0); + penpos2 (thin, 10); + + y1 = -2 staff_space_rounded; + y2 = h - vround lower_brush; + x2r = w; + z2 = z1 + whatever * dir (74); + z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10); + y9 := vround y9; + + x1l := hround x1l; + x1r := hround x1r; + x1 := .5 [x1l, x1r]; + + pat = z1l + -- z2l + .. z9 + .. z2r + -- z1r + .. cycle; + bulb_a = draw_rest_bulb (.5 staff_space, + y2r, pat, 0.98, 1); + bulb_b = draw_rest_bulb (.5 staff_space - staff_space_rounded, + hround ((-0.5 + 0.2) * staff_space), + pat, 1.02, 1); + + fill simple_serif (z1l, z1r, 40) + -- z2r + .. z9 + .. bulb_a + -- bulb_b + -- z1l + .. cycle; + + penlabels (1, 2); + labels (9); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("32th rest", "5"); + save ycenter; + save pat, bulb_a, bulb_b, bulb_c; + path pat, bulb_a, bulb_b, bulb_c; + + set_char_box (0, 1.3 staff_space#, + 2.0 staff_space# + 0.5 linethickness#, + 1.5 staff_space# + bulb_diam# / 2); + + penpos1 (thick, 0); + penpos2 (thin, 10); + + y1 = -2 staff_space_rounded; + y2 = h - vround lower_brush; + x2r = w; + z2 = z1 + whatever * dir (76); + z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10); + y9 := vround y9; + + x1l := hround x1l; + x1r := hround x1r; + x1 := .5 [x1l, x1r]; + + pat = z1l + -- z2l + .. z9 + .. z2r + -- z1r + .. cycle; + bulb_a = draw_rest_bulb (.5 staff_space + staff_space_rounded, + y2r, pat, 0.96, 1); + bulb_b = draw_rest_bulb (.5 staff_space, + hround ((0.5 + 0.2) * staff_space), + pat, 1.00, 1); + bulb_c = draw_rest_bulb (.5 staff_space - staff_space_rounded, + hround ((-0.5 + 0.21) * staff_space), + pat, 1.04, 1); + + fill simple_serif (z1l, z1r, 40) + -- z2r + .. z9 + .. bulb_a + -- bulb_b + -- bulb_c + -- z1l + .. cycle; + + penlabels (1, 2); + labels (9); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("64th rest", "6"); + save ycenter; + save pat, bulb_a, bulb_b, bulb_c, bulb_d; + path pat, bulb_a, bulb_b, bulb_c, bulb_d; + + set_char_box (0, 1.4 staff_space#, + 3.0 staff_space# + 0.5 linethickness#, + 1.5 staff_space# + bulb_diam# / 2); + + penpos1 (thick, 0); + penpos2 (thin, 10); + + y1 = -3 staff_space_rounded; + y2 = h - vround lower_brush; + x2r = w; + z2 = z1 + whatever * dir (78); + z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1) - 10); + y9 := vround y9; + + x1l := hround x1l; + x1r := hround x1r; + x1 := .5 [x1l, x1r]; + + pat = z1l + -- z2l + .. z9 + .. z2r + -- z1r + .. cycle; + bulb_a = draw_rest_bulb (.5 staff_space + staff_space_rounded, + y2r, pat, 0.94, 1); + bulb_b = draw_rest_bulb (.5 staff_space, + hround ((0.5 + 0.20) * staff_space), + pat, 0.98, 1); + bulb_c = draw_rest_bulb (.5 staff_space - staff_space_rounded, + hround ((-0.5 + 0.21) * staff_space), + pat, 1.02, 1); + bulb_d = draw_rest_bulb (.5 staff_space - 2 staff_space_rounded, + hround ((-1.5 + 0.22) * staff_space), + pat, 1.06, 1); + + fill simple_serif (z1l, z1r, 40) + -- z2r + .. z9 + .. bulb_a + -- bulb_b + -- bulb_c + -- bulb_d + -- z1l + .. cycle; + + penlabels (1, 2); + labels (9); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("128th rest", "7"); + save ycenter; + save pat, bulb_a, bulb_b, bulb_c, bulb_d, bulb_e; + path pat, bulb_a, bulb_b, bulb_c, bulb_d, bulb_e; + + set_char_box (0, 1.5 staff_space#, + 3.0 staff_space# + 0.5 linethickness#, + 2.5 staff_space# + bulb_diam# / 2); + + penpos1 (thick, 0); + penpos2 (thin, 10); + + y1 = -3 staff_space_rounded; + y2 = h - vround lower_brush; + x2r = w; + z2 = z1 + whatever * dir (80); + z9 = z2 + 0.5 linethickness * dir (angle (z2 - z1)- 10); + y9 := vround y9; + + x1l := hround x1l; + x1r := hround x1r; + x1 := .5 [x1l, x1r]; + + pat = z1l + -- z2l + .. z9 + .. z2r + -- z1r + .. cycle; + bulb_a = draw_rest_bulb (.5 staff_space + 2 staff_space_rounded, + y2r, pat, 0.92, 1); + bulb_b = draw_rest_bulb (.5 staff_space + staff_space_rounded, + hround ((1.5 + 0.20) * staff_space), + pat, 0.96, 1); + bulb_c = draw_rest_bulb (.5 staff_space, + hround ((0.5 + 0.21) * staff_space), + pat, 1.0, 1); + bulb_d = draw_rest_bulb (.5 staff_space - staff_space_rounded, + hround ((-0.5 + 0.22) * staff_space), + pat, 1.04, 1); + bulb_e = draw_rest_bulb (.5 staff_space - 2 staff_space_rounded, + hround ((-1.5 + 0.23) * staff_space), + pat, 1.08, 1); + + fill simple_serif (z1l, z1r, 40) + -- z2r + .. z9 + .. bulb_a + -- bulb_b + -- bulb_c + -- bulb_d + -- bulb_e + -- z1l + .. cycle; + + penlabels (1, 2); + labels (9); + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_endgroup ("rests"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-generic.mf b/muse2/share/scoreglyphs/feta-original/feta-generic.mf new file mode 100644 index 00000000..f2c90cdf --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-generic.mf @@ -0,0 +1,57 @@ +% +% feta-generic.mf -- implement generic stuff: include lots of files, but don't +% set dims. +% +% source file of the Feta (defintively not an abbreviation for Font-En-Tja) +% music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + + +if test = -1: + mode := smoke; +fi + +staffsize# := design_size * pt#; + +mode_setup; + +input feta-macros; + +input feta-params; + +font_x_height staff_space#; + +%% this is a fallback so we can run the font without including feta-bolletjes. +black_notehead_width# := 1.0 staff_space#; + + +fet_beginfont ("feta", design_size, "fetaMusic"); + +if test = 0: + input feta-eindelijk; + input feta-toevallig; + input feta-arrow; + input feta-puntje; + input feta-bolletjes; + input feta-schrift; + input feta-banier; + input feta-klef; + input feta-timesig; + input feta-pendaal; + input feta-haak; + input feta-accordion; +else: + input feta-test-generic.mf; +fi + +autometric_parameter ("staffsize", staffsize#); +autometric_parameter ("stafflinethickness", stafflinethickness#); +autometric_parameter ("staff_space", staff_space#); +autometric_parameter ("linethickness", linethickness#); +autometric_parameter ("black_notehead_width", black_notehead_width#); +autometric_parameter ("ledgerlinethickness", ledgerlinethickness#); +autometric_parameter ("blot_diameter", blot_diameter#); + +fet_endfont; diff --git a/muse2/share/scoreglyphs/feta-original/feta-haak.mf b/muse2/share/scoreglyphs/feta-original/feta-haak.mf new file mode 100644 index 00000000..ddc01c08 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-haak.mf @@ -0,0 +1,92 @@ +% feta-haak.mf -- implement bracket tips -*-Fundamental-*- +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 2005--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +fet_begingroup ("brackettips"); + +def draw_bracket (expr thick_sharp, width_sharp, updown) = +begingroup; + save p, thin, thick, flattening, width, hair, flare; + path p; + pair tipdir; + + flattening = 0.72; + thick# = thick_sharp; + flare# = flattening * width#; + width# = width_sharp; + + define_pixels (thick, width, flare); + if updown = 1: + set_char_box (0, width#, + .5 thick#, flare#); + else: + set_char_box (0, width#, + flare#, .5 thick#); + fi; + + thin = 2 linethickness; + hair = 1.25 linethickness; + + pickup pencircle scaled thin; + y7 = y1; + x7 = x2; + z2 = z4r + (thin, 0); + + penpos3 (thin, 0); + penpos4 (thin, 90); + + z3 = z4; + + top y3 = 0.5 thick; + lft x3 = 0.0; + x1 = x3l; + y1 = -0.5 thick; + + z8 = .5 [z2, z7]; + top y5 = flare; + rt x5 = width; + + p := z8{right} + ..tension 1.2.. z5{curl 0}; + tipdir := direction 1 of p; + + penpos5 (hair, angle tipdir); + penpos6 (hair, 90 + angle tipdir); + + z5 = z6; + + pickup pencircle scaled 1; + + fill (z1 + -- z3l{up} + .. z4r{right} + -- z2{right} + .. z6r{tipdir} + .. z5r + .. z6l{-tipdir} + ..tension 1.1.. z7{left} + & z7 + -- z1 + & cycle) yscaled updown; + + if updown = 1: + penlabels (1, 2, 3, 4, 5, 6, 7, 8); + fi; +endgroup; +enddef; + + +fet_beginchar ("bracket tip up", "up"); + draw_bracket (0.45 staff_space#, 1.9 staff_space#, 1); +fet_endchar; + + +fet_beginchar ("bracket tip down", "down"); + draw_bracket (0.45 staff_space#, 1.9 staff_space#, -1); +fet_endchar; + +fet_endgroup ("brackettips"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-klef.mf b/muse2/share/scoreglyphs/feta-original/feta-klef.mf new file mode 100644 index 00000000..15008d84 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-klef.mf @@ -0,0 +1,698 @@ +% feta-klef.mf -- implement Clefs -*-Fundamental-*- +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>, +% Jan Nieuwenhuizen <janneke@gnu.org>, +% Juergen Reuter <reuter@ipd.uka.de> + + +fet_begingroup ("clefs"); + +% +% [Wanske] says the bulbs should be positioned about 1/4 right of the +% `arrow'. +% +% TODO: The hair-curve at z6r looks a little awkward. +% + +def draw_c_clef (expr reduction) = + save hair, norm, reduced_ss, right_edge; + save xoff; + + reduced_ss# = staff_space# * reduction; + norm# := 2/3 reduced_ss#; + hair# := 0.06 reduced_ss# + 0.5 linethickness#; + right_edge# = 15/4 norm# + 2 hair#; + define_pixels (norm, reduced_ss, right_edge); + define_whole_vertical_blacker_pixels (hair); + + set_char_box (0, right_edge#, 2 reduced_ss#, 2 reduced_ss#); + + % make unreduced glyph fit exactly into five staff lines + if reduction = 1: + h := d := 2 staff_space_rounded; + fi; + + % assure that the gap between the left and right stem + % has the same number of pixels as the thickness of the right + % stem + draw_block ((0, -d + feta_shift), + (3/4 norm + 1/2 hair, h)); + draw_block ((3/4 norm + 1/2 hair + hround (3/2 hair), -d + feta_shift), + (3/4 norm + 1/2 hair + 2 hround (3/2 hair), h)); + + % assure symmetry + h := h - feta_shift; + + pickup feta_fillpen; + + xoff = 3/4 norm + 1/2 hair + 2 hround (3/2 hair); + z5l = (xoff - 3/4 hair, 0); + z5r = (x4, 0); + + penpos1 (hair - pen_top - pen_bot, -90); + top z1l = (xoff + norm + hair, h); + + penpos2 (hround (norm - 3/2 hair) - pen_lft - pen_rt, 180); + rt z2l = (w, h / 2); + + penpos3 (hair - pen_top - pen_bot, 90); + bot z3l = ((right_edge - xoff) / 2 + xoff, + vround (.5 norm - 1.5 hair)); + + penpos4 (hair - pen_lft - pen_rt, 0); + top z4 = (xoff + 1/2 norm + 1/2 hair, + vfloor (reduced_ss - linethickness - .2 hair)); + + bot z6 = (xoff + 3/4 norm, vround (.5 norm - .5 hair)); + + save t; + t = 0.833; + + save pat; + path pat; + + pat = z5l{curl 1} + .. z4l{up} + .. z4r{down} + .. z3r{right} + ..tension t.. z2r{up} + ..tension t.. flare_path (top z1l, 180, 90, + hair, hfloor (norm - 1/2 hair), -1) + ..tension t.. z2l{down} + .. z3l{left} + .. z6 + .. z5r{down}; + + filldraw pat shifted (0, feta_shift) + -- reverse pat yscaled -1 shifted (0, -feta_eps) + -- cycle; + + penlabels (1, 2, 3, 4, 5, 6); + + % ugh, should be bulb, not flare? + + draw_staff (-2, 2, 0); +enddef; + + +fet_beginchar ("C clef", "C"); + draw_c_clef (1.0); +fet_endchar; + + +fet_beginchar ("C clef", "C_change"); + draw_c_clef (.8); +fet_endchar; + + +% +% New bulb routine: +% +% Insert a brushed piece of the path, and draw the rest of the bulb +% separately. +% +% The bulb has circular form. Neat merging of the bulb and brushed path +% is done by playing with tension. +% + +def new_bulb (expr start_point, start_angle, + outer_tangent_point, + end_point, end_angle, + big_radius, bulb_radius, flare, + direction, turning_dir) = +begingroup; + save pat, before, after; + save center; + save u, v; + path pat, before, after; + pair center; + + clearxy; + + center = outer_tangent_point + + big_radius * dir (0); +% + (big_radius - bulb_radius) * dir (-turning_dir * 90) + + z1' = center + bulb_radius * dir (turning_dir * 180); + z2' = outer_tangent_point + flare * dir (0); + z3' = center + bulb_radius * dir (0); + z4' = center + bulb_radius * dir (turning_dir * 90); + z5' = center - 0.5 [big_radius, bulb_radius] * dir (turning_dir * 90); + + labels (1', 2', 3', 4', 5'); + + before := z3'{dir (turning_dir * 90)} + .. z4'{-dir (0)} + ..tension 1.1.. z1'{-dir (turning_dir* 90)}; + after := z2'{dir (turning_dir * 90)} + .. end_point{dir (end_angle)}; + (u, v) = before intersectiontimes after; + + pat := start_point{dir (start_angle)} + .. outer_tangent_point{dir (-turning_dir * 90)} + ..tension 1.02.. z5'{dir (0)} + .. subpath (0, u) of before + .. subpath (v, infinity) of after; + + if direction = 0: + pat := reverse pat; + fi + +pat +endgroup +enddef; + + +% +% There is some variation in the shape of bass clefs. +% +% * In some clefs the size of the swoosh tip almost reaches the +% bottom staff line; in some it crosses the 2nd line from the bottom +% with a small overshoot. +% +% The most popular design is where the X part of the tip is aligned +% with the left bulb boundary, and the Y part ends on the 2nd +% staffline exactly. This is what we do. +% +% * The diameter of the bulb is the width of the open space. +% +% * The vertical center of the bulb can be on or slightly above the +% staff line. +% +% * The vertical position of the dots can be symmetrical around the +% staffline, centered in the staff space. The Baerenreiter SCS has +% the bottom dot raised by approximately 0.1 staff space. +% +% * Uncarefully set music may have overshoots at the top. We have none. +% +% * It is not exactly clear where the vertical tangent at the right +% of the swoosh should be. +% + +def draw_bass_clef (expr exact_center, reduction) = + save reduced_ss, swoosh_width; + save right_thickness, right_offset, tip_protrude; + save dot_diam, bulb_y_offset, bulb_flare; + pair tip_protrude; + + reduced_ss# = staff_space# * reduction; + 2.2 dot_diam# = reduction * (staff_space# - stafflinethickness#); + right_thickness# = 0.37 staff_space# + 1.2 linethickness#; + swoosh_width# = 2.1 reduced_ss#; + define_pixels (swoosh_width); + define_whole_pixels (reduced_ss); + define_whole_blacker_pixels (dot_diam, right_thickness); + + right_offset = 0.05 staff_space; + bulb_y_offset := 0.075 staff_space; + bulb_flare := 2.5 linethickness; +% tip_protrude := (-linethickness, -.2 staff_space); + tip_protrude := (0, 0); + + set_char_box (-xpart exact_center, + xpart exact_center + swoosh_width# + 7/12 reduced_ss#, + -ypart exact_center + 2.5 reduced_ss#, + ypart exact_center + reduced_ss#); + + y1 = bulb_y_offset; + x1 = 0; + + x2 = .5 [x1, x3]; + x2l = x2r = x2; + + y2l := vround_pixels (reduced_ss# + 0.5 linethickness#); + y2l - y2r = linethickness; + + x3l - x1 = swoosh_width; + x3l - x3r = right_thickness; + + % optical correction: the top dot seems farther away if y3l = 0. + y3l = right_offset; + + z4 = -(0, 2.0 reduced_ss) + tip_protrude; + + penpos3 (whatever, 185); + penpos4 (linethickness, 135); + + fill new_bulb (z2l, 180, z1, z2r, 0, + 0.45 reduced_ss, 0.4 reduced_ss, + bulb_flare, 1, 1) + .. z3r{down} + .. {curl 0}simple_serif (z4r, z4l, 90){curl 0} + .. z3l{up} + ..tension 0.9.. cycle; + + pickup pencircle scaled dot_diam; + + lft x5 = hround (x3l + 1/3 reduced_ss - dot_diam / 2); + bot y5 = vfloor (.5 reduced_ss - dot_diam / 2); + z6 = z5 yscaled -1; + + % for symmetry + y5 := y5 + feta_shift; + + drawdot z5; + drawdot z6; + + penlabels (1, 2, 3, 4, 5, 6); + + draw_staff (-3, 1, 0); +enddef; + + +fet_beginchar ("F clef ", "F"); + draw_bass_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("F clef (reduced)", "F_change"); + draw_bass_clef ((0, 0), 0.8); +fet_endchar; + + + +% +% Inspired by Baerenreiter +% +% +% Beste lezers, kijk, +% +% Een bolletje hebben we bij toeval allemaal wel eens getekend, maar begint u +% toch eenvoudig. Eerst een eenvoudig kruis of herstellingsteken +% en via de dubbelslag naar een voorzichtig vlaggetje, en heb geduld! +% Ikzelf heb bijvoorbeeld over mijn eerste gave G-sleutel +% 35 kilobyte metafont, 12 patchlevels, 0 vriendinnen en 45 dagen gedaan +% +% -- vrij naar Van Kooten & De Bie +% + +def debugfill = fill enddef; + +def draw_gclef (expr reduction) = + save reduced_ss, downstroke_dir, downstroke_angle, center; + save breapth_factor, inner_thick_end, thinness, thickness, thinnib; + save start_angle, inner_start_angle, thinness; + save upward_swoosh_angle, bot_angle; + save pat; + path pat; + pair downstroke_dir, center; + + reduced_ss# = staff_space# * reduction; + define_pixels (reduced_ss); + + thinness = 0.095 staff_space + 0.75 linethickness; + downstroke_dir = unitvector (14, -75); + downstroke_angle = angle downstroke_dir; + bot_angle = -180; % downstroke_angle - 87 + + upward_swoosh_angle = 132; + start_angle = -97; + + breapth_factor = 21/14; + inner_thick_end = 45; + inner_start_angle = downstroke_angle - 43; + thickness = .32 reduced_ss + 1.1 linethickness; + + thinnib = thinness; + + set_char_box (0, 1.71 * breapth_factor * reduced_ss#, + 2.6 * reduced_ss#, 5 * reduced_ss#); + + center := (breapth_factor * reduced_ss, 0); + + z1 = center + whatever * dir (inner_start_angle); + x1 = xpart center - .28 reduced_ss; + penpos1 (thinnib, inner_start_angle); + + x2r = xpart center; + y2r = vround_pixels (reduced_ss# + .5 stafflinethickness#); + penpos2 (thickness, 90); + + z3 = (z4 - center) rotated inner_thick_end + center; + penpos3 (thinnib, -90 + inner_thick_end); + + x4 = xpart center - .1 reduced_ss; + y4r = -y2r + feta_shift; + penpos4 (thinnib, -90); + + x5r = -breapth_factor * reduced_ss + xpart center; + y5r = .37 reduced_ss + ypart center; + penpos5 (thickness, upward_swoosh_angle); + + z6 = center + whatever * downstroke_dir; + y6 = ypart center + 2 reduced_ss; + % penpos6 is computed later + + z7l - z6 = whatever * (z5 - z6) ; + y7l = 3.5 reduced_ss; + penpos7 (thickness, upward_swoosh_angle); + + x9 = .7 [x10, x7r]; + top y9l = 5 reduced_ss; + penpos9 (1.45 thickness, -70); + + x11 - x13r = 1.5 reduced_ss + 0.5 thinnib; + y11 = ypart center - 47/28 reduced_ss; + y12 = ypart center - 71/28 reduced_ss; + y13 = .48 [y12, y4r]; + x12r = xpart (.45 [z13r, z11] + .75 reduced_ss * downstroke_dir); + +% z10 = center + whatever * dir (downstroke_angle - 1.5); + x10 = x6 - 2 thinnib; + y10 = ypart center + 3.5 reduced_ss; + y10l - y10r = 1.0 thickness; + z10r - z10l = .7 thinnib * dir (downstroke_angle + 90) + + whatever * downstroke_dir; + z10 = .5 [z10l, z10r]; + z11 = center + whatever * downstroke_dir + (-0.05 reduced_ss, 0); + + penpos11 (thinnib, start_angle + 90); + penpos12 (thinnib, bot_angle + 90); + penpos13 (thinnib + 0.14 staff_space, 180); + + % this auxiliary point ensures good contour overlapping + z8 = .5 [z9l, z9r] + .25 ((z9r - z9l) rotated -90); + + z20 = z9l - (0, .25 blot_diameter); + penpos20 (blot_diameter, 0); + + pat := z10{down} + .. z6 + ..tension 1.1.. z11{dir (start_angle)}; + + penpos6 (thinnib, angle (direction 1 of pat) + 90); + + % two auxiliary points to simulate `draw' with `penstroke' + z10' = point 0.3 of pat; + penpos10' (1.3 thinnib, angle (direction 0.3 of pat) + 50); + + z11' = point 1.5 of pat; + penpos11' (thinnib, angle (direction 1.5 of pat) + 90); + + z21l = z20l; + z21r = z9r; + + pat := z21l + .. z10l{down} + .. z10'l; + + fill z2l{right} + .. z3l + .. z4l{left} + ..tension 1.07.. z5l{up} % inside curve + .. z7l{up} + ..tension 1.2.. z20r{curl 1} + .. {direction 0 of pat}z20l + -- z8 + -- z9r % {dir (downstroke_angle + 0)} + ..tension 0.8.. z7r{down} + .. z5r{down} + .. z4r{right} + .. z3r + .. z2r{left} + ..tension .95.. z1r + -- simple_serif (z1r, z1l, 80) + -- z1l + ..tension 0.85.. cycle; + + penstroke z21e + .. z10e{down} + .. z10'e + .. z6e + .. z11'e + .. z11e{dir (-95)} + .. z12e{dir (bot_angle)}; + + fill new_bulb (z12r, bot_angle, z13r, z12l, bot_angle + 180, + 0.45 reduced_ss, 0.38 reduced_ss, + thinnib + .05 staff_space, 1, -1) + -- cycle; + + penlabels (range 1 thru 21); + penlabels (10', 11'); + + draw_staff (-1, 3, 0); +enddef; + + +fet_beginchar ("G clef", "G"); + draw_gclef (1.0); +fet_endchar; + + +fet_beginchar ("G clef", "G_change"); + draw_gclef (0.8); +fet_endchar; + + +%%%% +% +% PERCUSSION +% + +% +% The percussion clef extent is not coincident with its bbox, since +% the percussion clef needs more space in front than a normal clef. +% + +def draw_percussion_clef (expr reduction) = + save reduced_ss, razt; + + reduced_ss# = staff_space# * reduction; + define_pixels (reduced_ss); + + set_char_box (-.67 reduced_ss#, 2.0 reduced_ss#, + reduced_ss#, reduced_ss#); + + razt := hround (0.45 reduced_ss); + + d := d - feta_shift; + + draw_block ((-b, -d), (-b + razt, h)); + draw_block ((w - razt, -d), (w, h)); + + draw_staff (-3, 1, 1); +enddef; + + +fet_beginchar ("percussion clef", "percussion"); + draw_percussion_clef (1.0); +fet_endchar; + + +fet_beginchar ("percussion clef (reduced)", "percussion_change"); + draw_percussion_clef (.8); +fet_endchar; + + +def draw_tab_T (expr pos, siz, slant) = +begingroup; + save vx, vy; + pair vx, vy; + + clearxy; + + vx = (xpart siz) * dir 0; + vy = (ypart siz) * dir 90; + + penpos1 (.75 penh, 100); + z1 = z2 + (1/6 * vx - .15 * vy); + penpos2 (hround (.9 penw), 0); + x2l = hround xpart (pos + .75 vy); + y2l = ypart (pos + .75 vy); + penpos3 (penh, -100); + z3l = pos + .4 vx + vy; + penpos4 (penh, -90); + z4 = -.1 vy + .5 [z3, z5]; + penpos5 (.8 penh, -30); + x5r = xpart (pos + siz); + y5l = ypart (pos + siz); + + penpos10 (penw, 170); + z10 = pos + .55 vx + .9 vy; + penpos11 (.75 [penh, penw], 170); + z11 = z10 - .5 vy + .025 vx; + penpos12 (penh, 100); + z12l = (xpart .5 [z13, z11], ypart (pos - .025 * siz)); + penpos13 (.75 penh, 60); + z13 = pos + .2 vx + .15 vy; + + % penlabels (range 1 thru 13); + + soft_penstroke (z1e + ..tension 1.1.. z2e + .. z3e{right} + ..tension 1.5.. z4e + ..z5e) + slanted slant shifted (slant * -ypart pos, 0); + + soft_end_penstroke (z10e + ..tension 1.5.. z11e + .. z12e + ..tension 1.1.. z13e{(z13r - z13l) rotated 90}) + slanted slant shifted (slant * -ypart pos, 0); +endgroup; +enddef; + + +def draw_tab_A (expr pos, siz, slant) = +begingroup; + save vx, vy, pat; + pair vx, vy; + path pat; + + clearxy; + + vx = (xpart siz) * dir 0; + vy = (ypart siz) * dir 90; + + penpos1 (.75 penh, -110); + z1r = pos + .07 vy; + penpos2 (penh, -75); + z2r = (.5 [x1, x3], ypart pos); + penpos3 (.25 [penh, penw], -30); + z3 = (.45 [x2, x4], .15 [y2, y4]); + penpos4 (1 [penh, penw], 0); + z4 = pos + .5 vx + .975 vy; + + penpos5 (1 [penh, penw], -180); + z5 = z4; + penpos6 (.2 [penh, penw], -150); + z6l = (.8 [x5l, x7l], .9 [y5l, y7l]); + penpos7 (penh,-90); + z7r = (.5 [x6, x8], ypart pos); + penpos8 (.75 penh, -70); + z8r = (xpart (pos + siz), y7r + .075 ypart (siz)); + + pat := z2 + .. z3 + .. z4; + + penpos10 (penh, angle (direction 1.2 of pat) - 180); + z10 = point 1.2 of pat; + penpos11 (.9 penh, -90); + z11 = .4 [z10, z6] - 0.05 vy; + penpos12 (.75 penh, -75); + z12 = .3 [z11, z6] + 0.02 vy; + + % penlabels (range 1 thru 12); + + soft_penstroke (z1e{(z1r - z1l) rotated 90} + .. z2e + .. z3e + .. z4e) + slanted slant shifted (slant * -ypart pos, 0); + + soft_end_penstroke (z5e + .. z6e + .. z7e + .. z8e{(z8r - z8l) rotated 90}) + slanted slant shifted (slant * -ypart pos, 0); + + soft_end_penstroke (z10e + .. z11e + .. z12e) + slanted slant shifted (slant * -ypart pos, 0); +endgroup; +enddef; + + +def draw_tab_B (expr pos, siz, slant) = +begingroup; + save vx, vy; + pair vx, vy; + + clearxy; + + vx = (xpart siz) * dir 0; + vy = (ypart siz) * dir 90; + + penpos1 (.75 penh, 100); + z1 = z2 + (.15 * vx - .1 * vy); + penpos2 (hround (.9 penw), 0); + x2l = hround xpart (pos + .75 vy); + y2l = ypart (pos + .75 vy); + penpos3 (penh, -100); + z3l = pos + .4 vx + 1.05 vy; + penpos4 (.8 [penh, penw], -180); + z4 = (xpart (pos + .75 siz), .5 [y3, y5]); + penpos5 (.8 penh, 90); + z5 = (.5 [x10, x4], ypart (pos + .55 siz)); + + penpos6 (.8 penh, 270); + z6 = z5; + penpos7 (penw, 180); + z7l = (xpart (pos + siz), .5 [y6, y8]); + penpos8 (.8 penh, 45); + z8 = .5 [z12l, z11l] + .15 vx - .05 vy; + + penpos10 (.75 [penh, penw], 170); + z10 = pos + .375 vx + vy; + penpos11 (.8 [penh, penw], 150); + z11 = z10 - .5 vy + .04 vx; + penpos12 (penh, 100); + z12l = (xpart .5 [z13, z11], ypart pos); + penpos13 (.75 penh, 60); + z13 = pos + .1 vx + .15 vy; + + % penlabels (range 1 thru 13); + + soft_penstroke (z1e + ..tension 1.1.. z2e + .. z3e + .. z4e + ..z5e {left}) + slanted slant shifted (slant * -ypart pos, 0); + + soft_end_penstroke (z6e{right} + .. z7e + .. z8e{(z8r - z8l) rotated 90}) + slanted slant shifted (slant * -ypart pos, 0); + + soft_end_penstroke (z10e + ..tension 1.5.. z11e + .. z12e + ..tension 1.1.. z13e{(z13r - z13l) rotated 90}) + slanted slant shifted (slant * -ypart pos, 0); +endgroup; +enddef; + + +def draw_tab_clef (expr reduction) = + save reduced_ss, letterheight, penw, penh; + + reduced_ss# = staff_space# * reduction; + letterheight# = 1.8 reduced_ss#; + define_pixels (reduced_ss, letterheight); + + set_char_box (-.2 reduced_ss#, 2.8 reduced_ss#, + 1.6 letterheight#, 1.6 letterheight#); + + penw = .45 reduced_ss; + penh = .2 reduced_ss; + + draw_tab_T ((-b + .15 reduced_ss, h - letterheight), + (2.1 reduced_ss, letterheight), 0.2); + draw_tab_A ((-b - .05 reduced_ss, -.5 letterheight +.15 reduced_ss), + (2.2 reduced_ss, letterheight), 0.4); + draw_tab_B ((-b + .025 reduced_ss, -d), + (2.1 reduced_ss, letterheight), 0.25); + + draw_staff (-3, 2, 0.5); +enddef; + + +fet_beginchar ("tab clef", "tab"); + draw_tab_clef (1.0); +fet_endchar; + + +fet_beginchar ("tab clef (reduced)", "tab_change"); + draw_tab_clef (.8); +fet_endchar; + +fet_endgroup ("clefs"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-macros.mf b/muse2/share/scoreglyphs/feta-original/feta-macros.mf new file mode 100644 index 00000000..19cc379a --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-macros.mf @@ -0,0 +1,497 @@ +% +% feta-macros.mf -- auxiliary macros for both feta and parmesan fonts +% +% source file of the GNU LilyPond music typesetter +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + + +% +% debugging +% + +def print_penpos (suffix $) = + message + "z" & str$ & "l = (" & decimal x.$.l & ", " &decimal y.$.l & ");" + & " z" & str$ & "r = (" & decimal x.$.r & ", " & decimal y.$.r & ");"; +enddef; + + +def test_grid = + if test > 1: + proofrulethickness 1pt#; + + makegrid + (0pt, 0pt for i := -5pt step 1pt until 5pt: , i endfor) + (0pt, 0pt for i := -5pt step 1pt until 5pt: , i endfor); + + proofrulethickness .1pt#; + + makegrid + (0pt, 0pt for i := -4.8pt step .2pt until 4.8pt: , i endfor) + (0pt, 0pt for i := -4.8pt step .2pt until 4.8pt: , i endfor); + fi; +enddef; + + +def treq = + tracingequations := tracingonline := 1; +enddef; + + +def draw_staff (expr first, last, offset) = + if test <> 0: + pickup pencircle scaled stafflinethickness; + + for i := first step 1 until last: + draw (-staff_space, + (i + offset) * staff_space_rounded) + -- (4 staff_space, + (i + offset) * staff_space_rounded); + endfor; + fi; +enddef; + + +% +% Draw the outline of the stafflines. For fine tuning. +% + +def draw_staff_outline (expr first, last, offset) = + if test <> 0: + save p; + path p; + + pickup pencircle scaled 2; + + for i := first step 1 until last: + p := (-staff_space, + (i + offset) * staff_space_rounded) + -- (4 staff_space, + (i + offset) * staff_space_rounded); + + draw p shifted (0, .5 stafflinethickness); + draw p shifted (0, -.5 stafflinethickness); + endfor; + fi; +enddef; + + +% +% Transformations +% + +def scaledabout (expr point, scale) = + shifted -point scaled scale shifted point +enddef; + + +% +% make a local (restored after endgroup) copy of t_var +% + +def local_copy (text type, t_var) = + save copy_temp; + type copy_temp; + copy_temp := t_var; + save t_var; + type t_var; + t_var := copy_temp; +enddef; + + +% +% Urgh! Want to do parametric types +% + +def del_picture_stack = + save save_picture_stack, picture_stack_idx; +enddef; + + +% +% better versions of Taupin/Egler savepic cmds +% + +def make_picture_stack = + % override previous stack + del_picture_stack; + picture save_picture_stack[]; + numeric picture_stack_idx; + picture_stack_idx := 0; + + def push_picture (expr p) = + save_picture_stack[picture_stack_idx] := p; + picture_stack_idx := picture_stack_idx + 1; + enddef; + + def pop_picture = save_picture_stack[decr picture_stack_idx] enddef; + def top_picture = save_picture_stack[picture_stack_idx] enddef; +enddef; + + +% +% save/restore pens +% why can't I delete individual pens? +% + +def make_pen_stack = + del_pen_stack; + pen save_pen_stack[]; + numeric pen_stack_idx; + pen_stack_idx := 0; + def push_pen (expr p) = + save_pen_stack[pen_stack_idx] := p; + pen_stack_idx := pen_stack_idx + 1; + enddef; + def pop_pen = save_pen_stack[decr pen_stack_idx] enddef; + def top_pen = save_pen_stack[pen_stack_idx] enddef; +enddef; + + +def del_pen_stack = + save save_pen_stack, pen_stack_idx; +enddef; + + +% +% drawing +% + +def soft_penstroke text t = + forsuffixes e = l, r: + path_.e := t; + endfor; + + if cycle path_.l: + cyclestroke_; + else: + fill path_.l + ..tension1.5.. reverse path_.r + ..tension1.5.. cycle; + fi; +enddef; + + +def soft_start_penstroke text t = + forsuffixes e = l, r: + path_.e := t; + endfor; + + if cycle path_.l: + cyclestroke_; + else: + fill path_.l + -- reverse path_.r + ..tension1.5.. cycle; + fi; +enddef; + + +def soft_end_penstroke text t = + forsuffixes e = l, r: + path_.e := t; + endfor; + + if cycle path_.l: + cyclestroke_; + else: + fill path_.l + ..tension1.5.. reverse path_.r + -- cycle; + fi; +enddef; + + +% +% Make a round path segment going from P to Q. 2*A is the angle that the +% path should take. +% + +def simple_serif (expr p, q, a) = + p{dir (angle (q - p) - a)} + .. q{-dir (angle (p - q) + a)} +enddef; + + +% +% Draw an axis aligned block making sure that edges are on pixels. +% + +def draw_rounded_block (expr bottom_left, top_right, roundness) = +begingroup; + save size; + save x, y; + + % Originally, there was `floor' instead of `round', but this is + % not correct because pens use `round' also. + size = round min (roundness, + xpart (top_right - bottom_left), + ypart (top_right - bottom_left)); + + z2 + (size / 2, size / 2) = top_right; + z4 - (size / 2, size / 2) = bottom_left; + y3 = y2; + y4 = y1; + x2 = x1; + x4 = x3; + + pickup pencircle scaled size; + + fill bot z1{right} + .. rt z1{up} + -- rt z2{up} + .. top z2{left} + -- top z3{left} + .. lft z3{down} + -- lft z4{down} + .. bot z4{right} + -- cycle; +endgroup; +enddef; + + +def draw_block (expr bottom_left, top_right) = + draw_rounded_block (bottom_left, top_right, blot_diameter); +enddef; + + +def draw_square_block (expr bottom_left, top_right) = + save x, y; + + x1 = xpart bottom_left; + y1 = ypart bottom_left; + x2 = xpart top_right; + y2 = ypart top_right; + + fill (x1, y1) + -- (x2, y1) + -- (x2, y2) + -- (x1, y2) + -- cycle; +enddef; + + +def draw_gridline (expr bottom_left, top_right, thickness) = + draw_rounded_block (bottom_left - (thickness / 2, thickness / 2), + top_right + (thickness / 2, thickness / 2), + thickness); +enddef; + + +def draw_brush (expr a, w, b, v) = + save x, y; + + z1 = a; + z2 = b; + z3 = z4 = z1; + z5 = z6 = z2; + + penpos3 (w, angle (z2 - z1) + 90); + penpos4 (w, angle (z2 - z1)); + penpos5 (v, angle (z1 - z2) + 90); + penpos6 (v, angle (z1 - z2)); + + fill z3r{z3r - z5l} + .. z4l + .. {z5r - z3l}z3l + .. z5r{z5r - z3l} + .. z6l + .. {z3r - z5l}z5l + .. cycle; +enddef; + + +% +% Make a superellipsoid segment going from FROM to TO, with SUPERNESS. +% Take superness = sqrt(2)/2 to get a circle segment. +% +% See Knuth, p. 267 and p.126. + +def super_curvelet (expr from, to, superness, dir) = + if dir = 1: + (superness [xpart to, xpart from], + superness [ypart from, ypart to]){to - from} + else: + (superness [xpart from, xpart to], + superness [ypart to, ypart from]){to - from} + fi +enddef; + + +% +% Bulb with smooth inside curve. +% +% alpha = start direction +% beta = which side to turn to +% flare = diameter of the bulb +% line = diameter of line attachment +% direction = is ink on left or right side (1 or -1) +% +% Note that `currentpen' must be set correctly -- only circular pens +% are supported properly. + +def flare_path (expr pos, alpha, beta, line, flare, direction) = +begingroup; + save thick; + + thick = pen_top + pen_bot; + + clearxy; + + penpos1' (line - thick, 180 + beta + alpha); + top z1'r = pos; + + penpos2' (flare - thick, 180 + beta + alpha); + z2' = z3'; + + penpos3' (flare - thick, 0 + alpha); + rt x3'l = hround (x1'r + + (1/2 + 0.43) * flare * xpart dir (alpha + beta)); + bot y2'l = vround (y1'r + + (1 + 0.43) * flare * ypart dir (alpha + beta)); + + rt x4' = x2'r - line * xpart dir (alpha); + y4' = y2'r - line * ypart dir (alpha); + + penlabels (1', 2', 3', 4'); + + save t, p; + t = 0.833; + path p; + + p := z1'r{dir (alpha)} + .. z3'r{dir (180 + alpha - beta)} + .. z2'l{dir (alpha + 180)} + .. z3'l{dir (180 + alpha + beta)} + ..tension t.. z4'{dir (180 + alpha + beta)} + .. z1'l{dir (alpha + 180)}; + + if direction <> 1: + p := reverse p; + fi; + +p +endgroup +enddef; + + +def brush (expr a, w, b, v) = +begingroup; + draw_brush (a, w, b, v); + penlabels (3, 4, 5, 6); +endgroup; +enddef; + + +% +% Draw a (rest) crook, starting at thickness STEM in point A, +% ending a ball W to the left, diameter BALLDIAM. +% ypart of the center of the ball is BALLDIAM/4 lower than ypart A. +% + +def balled_crook (expr a, w, balldiam, stem) = +begingroup; + save x, y; + + penpos1 (balldiam / 2, -90); + penpos2 (balldiam / 2, 0); + penpos3 (balldiam / 2, 90); + penpos4 (balldiam / 2, 180); + + x4r = xpart a - w; + y3r = ypart a + balldiam / 4; + x1l = x2l = x3l = x4l; + y1l = y2l = y3l = y4l; + + penpos5 (stem, 250); + x5 = x4r + 9/8 balldiam; + y5r = y1r; + + penpos6 (stem, 260); + x6l = xpart a; + y6l = ypart a; + + penstroke z1e + .. z2e + .. z3e + .. z4e + .. z1e + .. z5e{right} + .. z6e; + + penlabels (1, 2, 3, 4, 5, 6); +endgroup; +enddef; + + +def y_mirror_char = + currentpicture := currentpicture yscaled -1; + + set_char_box (charbp, charwd, charht, chardp); +enddef; + + +def xy_mirror_char = + currentpicture := currentpicture scaled -1; + + set_char_box (charwd, charbp, charht, chardp); +enddef; + + +% +% center_factor: typically .5; the larger, the larger the radius of the bulb +% radius factor: how much the bulb curves inward +% + +def draw_bulb (expr turndir, zl, zr, bulb_rad, radius_factor)= +begingroup; + save rad, ang, pat; + path pat; + + clearxy; + + ang = angle (zr - zl); + + % don't get near infinity + % z0 = zr + bulb_rad * (zl - zr) / length (zr - zl); + z0' = zr + bulb_rad / length (zr - zl) * (zl - zr); + + rad = bulb_rad; + + z1' = z0' + radius_factor * rad * dir (ang + turndir * 100); + z2' = z0' + rad * dir (ang + turndir * 300); + + labels (0', 1', 2'); + + pat = zr{dir (ang + turndir * 90)} + .. z1' + .. z2' + .. cycle; + + % avoid grazing outlines + fill subpath (0, 2.5) of pat + -- cycle; +endgroup +enddef; + + +pi := 3.14159; + + +% +% To get symmetry at low resolutions we need to shift some points and +% paths, but not if mf2pt1 is used. +% + +if known miterlimit: + vardef hfloor primary x = x enddef; + vardef vfloor primary y = y enddef; + vardef hceiling primary x = x enddef; + vardef vceiling primary y = y enddef; +else: + vardef hfloor primary x = floor x enddef; + vardef vfloor primary y = (floor y.o_)_o_ enddef; + vardef hceiling primary x = ceiling x enddef; + vardef vceiling primary y = (ceiling y.o_)_o_ enddef; +fi; diff --git a/muse2/share/scoreglyphs/feta-original/feta-nummer-code.mf b/muse2/share/scoreglyphs/feta-original/feta-nummer-code.mf new file mode 100644 index 00000000..ab8fe9f0 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-nummer-code.mf @@ -0,0 +1,899 @@ +% feta-nummer-code.mf -- implement bold Orator numerals +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 1997--2009 Jan Nieuwenhuizen <janneke@gnu.org> + + +height# := number_design_size; +space# := number_design_size / 2; + +font_x_height height#; +font_normal_space space#; + + +% +% DOCME! +% +% ugh. b and h are reused. +% + +save b, h; +4 h + b = 1.15; +10 h + b = 1; +fatten := number_design_size * h + b; + +save b, h; +4 h + b = 1.05; +10 h + b = 1; +widen := number_design_size * h + b; + +tense = 0.85; +thick# := 7/30 height# * fatten; +thin# := thick# / 4 * fatten + max (.1 (height# / 10 - 1), 0); + +%% sqrt (.8 * blot_diameter# * thin#); +hair# := thin# * .8; + +flare# := 9/8 thick# + .75 (height# / 10 - 1); + +save b, h; +4h + b = 1/8; +10h + b = 1/6; +kuulleke# := thick# * number_design_size * h + b; +foot_top# := thick#; +foot_width# := 9/4 thick#; + + +% +% These numbers were taken from a part that that the EJE violas played +% 1997 -- Probably Mendelssohn's ouverture `Heimkehr aus der Fremde'. +% + + +% +% TODO all the invocation of flare_path are weird -- +% the horizontal tangents should be more at the center of the +% glyph. +% + +define_pixels (height, thick, thick, thin, hair, flare); +define_pixels (foot_top, foot_width); +define_pixels (kuulleke); + + +% +% Yet Another Bulb Routine with smooth inside curve. +% +% alpha = start direction. +% beta = which side to turn to +% flare = diameter of the bulb +% line = diameter of line attachment +% direction = is ink on left or right side (1 or -1) +% +% +% move_away_to = amount left (for 2) +% turn_to = amount down (for 2) +% + +def number_flare_path (expr pos, alpha, beta, line, flare, + move_away_to, turn_to, taille, taille_ratio, + direction) = +begingroup; + save res; + path res; + + clearxy; + +% z5 = z2 + 0.43 * flare * dir (alpha - 1.5 beta); + + z4 = (0.75 - taille) [z2r, z2l] + whatever * dir (alpha - beta); + z4 = (taille_ratio * taille) [z3l, z3r] + whatever * dir (alpha); + + z1r = pos; + z2r = z1r + move_away_to * dir (alpha) + + (line + turn_to) * dir (alpha + beta); + z3r = 0.5 [z2l, z2r] + 0.5 * flare * dir (alpha + beta); + + penpos1 (line, 180 + beta + alpha); + penpos2 (flare, alpha); + penpos3 (flare, alpha + beta); + + penlabels (1, 2, 3, 4, 5); + + res := z1r{dir (alpha)} + .. z2r{dir (180 + alpha - beta)} + .. z3r{dir (alpha + 180)} + .. z2l{dir (alpha - beta)} + +%%% Two versions of the curve: one with z4, the other with z5. +% .. z5{dir (alpha - beta / 2)} + + .. z4{dir (180 + alpha + beta)} + .. z1l{dir (alpha + 180)}; + +% pickup pencircle; +% draw res; + + if direction <> 1: + res := reverse res; + fi; + +res +endgroup +enddef; + + +def calc_kuulleke (expr w, alpha) = +begingroup; + save beta, gamma; + + beta = (alpha - 90) / 2; + gamma = (90 + alpha) / 2; + + penpos1 (w / cosd (alpha), alpha); + penpos2 (hair, 90 + beta); + penpos3 (hair, gamma - 90); + + z2 = z1l + (1/2 hair / tand ((alpha + 90) / 2)) * dir (beta); + z3 = z1r - (1/2 hair / tand ((90 - alpha) / 2)) * dir (gamma); + z4 = z1 + kuulleke * dir (alpha - 90); +endgroup; +enddef; + + +% should make generic macro? +% +def draw_foot (expr xpos) = +begingroup; + clearxy; + + penpos1 (thick, 0); + penpos2 (foot_width, 0); + penpos3 (hair, -90); + penpos4 (hair, 90); + + z1= (xpos, foot_top); + z2= (x1, 0); + z3r = z2r; + z4l = z2l; + z5 = (x1, kuulleke); + + penlabels (1, 2, 3, 4); + + fill z1 + .. {right}z1r{down} + .. {right}z3l + .. z3r{left} + .. z5 + .. {left}z4l + .. z4r{right} + .. {up}z1l{right} + .. z1 + .. cycle; +endgroup; +enddef; + + +def draw_six = + save outer_t, t; + save before, after, u, v; + path before, after; + + set_char_box (0, .68 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + penpos2 (hair, 90); + z2 = (w / 2, h / 2 + thin - hair / 2); + + penpos3 (15/16 thick, 0); + x3r = w; + y3r = .5 [y4r, y2r]; + + penpos4 (hair, -90); + z4r = (x2, 0); + + penpos6 (hair, 90); + x6r = .56 w; + y6r = h; + + penpos7 (thick, 180); + x7r = 0; + y7r = .50 h; + + penpos10 (thick, 180); + z10r = (0, y3); + + penlabels (range 1 thru 10); + + outer_t = 0.88; + t := tense; + + before := z7{right} + .. z2r{right}; + after := z7r{up} + .. number_flare_path (z6r, 0, -90, hair, flare, + w - x6r - hair / 2, .16 h, + 0.05, 2.5, 1) + .. z7l{down}; + (u, v) = before intersectiontimes after; + +% draw + fill subpath (u, infinity) of before + ..tension outer_t.. z3r{down} + ..tension outer_t.. z4r{left} + .. subpath (0, v) of after + .. cycle; + + unfill z2l{right} + ..tension t.. z3l{down} + ..tension t.. z4l{left} + ..tension t.. z10l{up} + ..tension t.. cycle; +enddef; + + +save dot_diam; +dot_diam# = 7/8 flare#; +define_pixels (dot_diam); + + +code := 42; % , 43 + +fet_beginchar ("Plus", "plus"); + set_char_box (0, .5 height#, -0.25 height#, 0.75 height#); + + save hthick, vthick, size, outer_hsize, outer_vsize; + + hthick# = vthick# = 2 linethickness#; + size# = 1.1 staff_space#; + define_whole_blacker_pixels (vthick); + define_whole_vertical_blacker_pixels (hthick); + + outer_hsize = hround ((b + w - vthick) / 2); + outer_vsize = vround ((h + d - hthick) / 2); + + centerx := hround (w / 2); + centery := vround ((h - d) / 2); + + z1 = (centerx - hthick / 2, -d); + z2 = (centerx + hthick / 2, h); + + labels (1, 2); + + draw_rounded_block (z1, z2, hthick); + draw_rounded_block ((0, centery - vthick / 2), + (w, (centery + vthick / 2)), + vthick); +fet_endchar; + + +code := 43; % , = 44 + +fet_beginchar ("Numeral comma", "comma"); + save pat, pos; + path pat; + + set_char_box (0, dot_diam#, 3/2 dot_diam#, dot_diam#); + + pat := (dot_diam / 2, 0) + .. (dot_diam, dot_diam / 2) + .. (dot_diam / 2, dot_diam) + .. (0, dot_diam / 2) + .. cycle; + + pos = ypart (((w / 3, 0) -- (w / 3, dot_diam / 2)) + intersectiontimes pat); + z0 = point pos of pat; + + alpha = 65; + penpos1 (thin, alpha + 90); + + z1l = (w / 2, -1.5 h + hair); + z2 = (w, h / 2); + + pickup feta_fillpen; + + % include z0 to assist removal of overlaps + fill subpath (0,3) of pat + .. z0 + .. cycle; + filldraw z1l{dir (alpha)} + .. {up}z2 + -- z0{direction pos of pat} + ..tension 0.95.. {dir (180 + alpha)}z1r + .. cycle; + + labels (0, 2); + penlabels (1); +fet_endchar; + + +fet_beginchar ("Numeral dash", "hyphen"); + set_char_box (0, height# / 3, 0, height#); + + draw_rounded_block ((-b, h / 3 - thin / 2), + (w, h / 3 + thin / 2), thin); +fet_endchar; + + +fet_beginchar ("Numeral dot", "period"); + set_char_box (0, dot_diam#, 0, dot_diam#); + + pickup pencircle scaled dot_diam; + + drawdot (dot_diam / 2, dot_diam / 2); +fet_endchar; + + +% skip slash + +code := 47; % 0 = 48 + +fet_beginchar ("Numeral 0", "zero"); + set_char_box (0, 11/15 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + penpos1 (thin, 90); + penpos2 (thick, 180); + penpos3 (thin,- 90); + penpos4 (thick, 0); + + z1r = (w / 2, h); + z2r = (0, h / 2); + z3r = (w / 2, 0); + z4r = (w, h / 2); + + fill z1r + .. z2r + .. z3r + .. z4r + .. cycle; + + save t; + t = 1 / tense; + + penlabels (1, 2, 3, 4); + + unfill z1l + ..tension t.. z2l + ..tension t.. z3l + ..tension t.. z4l + ..tension t.. cycle; +fet_endchar; + + +fet_beginchar ("Numeral 1", "one"); + save alpha, beta, gamma; + +% set_char_box (0, 19/30 height# * widen, 0, height#); + set_char_box (0, 1/2 foot_width# + 3/2 thick# + 1/2 hair#, + 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = 0; + calc_kuulleke (thick, alpha); + z1 = (3/2 thick, height); + + penpos5 (thick, 0); + z5 = (x1, foot_top); + + z6 = (0, h / 2); + beta = angle (z1l - z6); + + penpos7 (thin, beta - 90); + z7l = z6; + + penpos8 (thin / cosd (beta), -90); + z8l = z1l; + + penpos9 (thin, beta - 90); + z9r = z8r + (thin / cosd (beta)) * down; + + penlabels (range 1 thru 9); + + gamma = angle (length (z1r - z1), 2 kuulleke); + + fill z2r{dir (alpha - gamma)} + .. z4 + .. {dir (alpha + gamma)}z3l + .. z3r{down} + -- z5r + -- z5l + -- z2l{up} + .. cycle; + + fill z7l + -- z1l{dir (beta)} + .. {dir (alpha - gamma)}z2r + -- z9r{up} + .. {dir (180 + beta)}z9l + -- z7r{dir (180 + beta)} + .. {dir (beta)}cycle; + + draw_foot (x1); +fet_endchar; + + +fet_beginchar ("Numeral 2", "two"); + save tolerance; + save alpha, beta, gamma, theta; + save flare_start_distance; + save t, pat, bow; + path pat, bow; + + set_char_box (0, 22/30 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = -45 * widen; + beta = 85; + gamma = beta - 10; + theta = 20 / widen; + + flare_start = 0.25; + + penpos1 (hair, 90 + beta); + z1 = (0, 0) + (1/2 sqrt (2) * hair) * dir (45); + + penpos3 (hair,90 + gamma); + z3 = (w, thick) + (1/2 sqrt (2) * hair) * dir (-135); + + penpos2 (thick, 90 + alpha - 15); + x2 - x1 = x3 - x2; + y2 = 10/16 thick / widen; + + tolerance := epsilon; + + % Find proper tension to exactly touch the x axis. + % Later on we directly use `bow'. + vardef f (expr t) = + bow := z3l{dir (180 + gamma)} + ..tension t.. {dir (180 + alpha -5)}z2l; + ypart (directionpoint left of bow) < 0 + enddef; + + % the return value of `solve' is stored in a dummy variable + t = solve f (0.8, 1.2); + + fill z1r{dir (beta)} + ..tension 0.9.. {dir (alpha + 10)}z2r + .. {dir (gamma)}z3r + .. bow + .. {dir (180 + beta)}z1l + .. cycle; + + penpos4 (thick, 0); + z4r = (w - thin / 2, .71 h); + + penpos5 (hair, 90); + y5r = h; + x5r = 9/20 w; + + penlabels (range 1 thru 6); + + t := tense; + + pat := z1l{dir (beta)} + ..tension t.. z4r{up} + .. number_flare_path (z5r, 180, 90, hair, 1.05 flare, + x5r - 1/2 hair, .21 h, 0.006, 0.4, 1) + .. z4l{down} + ..tension t.. {dir (180 + beta)}z1r + -- cycle; + +% pickup pencircle scaled 1; +% draw pat; + + fill pat; +fet_endchar; + + +%% +% TODO: should widen a bit. The right edge of the 3 bumps into next glyph in +% combinations +% +fet_beginchar ("Numeral 3", "three"); + set_char_box (0, 2/3 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + penpos1 (hair, -90); + +% flare_start = 0.25; + + x1l = 36/80 w; + y1l = h; + +% z1l = (17/16 thick, h); + + penpos2 (7/8 thick, 180); + x2l = w - thick / 8; + y2l = 3/4 h + thick * 3/32; + + penpos3 (thin, 90); + z3 = (w / 2, h / 2 + 1/8 thick); + + penpos4 (thin, 90); + z4 = (5/8 thick + 1/2 thin, y3); + + penpos5 (thick, 0); + x5r = w; + y5r = 17/64 h + thick / 16; + + penpos6 (hair, -90); + x6r = 37/80 w; + y6r = 0; + + penpos7 (3/2 thin, 90); + x7 = .83 w; + y7 = y3; + + penlabels (range 1 thru 7); + + save alpha, t, outer_t; + alpha = 25; + t = tense; + outer_t := 0.93; + +% pickup pencircle scaled 1; +% draw + fill number_flare_path (z1l, 180, 90, hair, 7/8 flare, x1l - .5 hair, + .16 h, 0.06, 1.5, -1) + ..tension outer_t.. z2l{down} + ..tension outer_t.. z7r{dir (180 + alpha)} + .. z7l{dir (-alpha)} + ..tension outer_t.. z5r{down} + ..tension outer_t.. number_flare_path (z6r, 180, -90, hair, + flare, x6l, .18 h, 0.06, + 1.5, 1) + .. z5l{up} + ..tension t.. z3l{left} + .. z4l{left} + .. z4r{right} + .. z3r{right} + ..tension t.. z2r{up} + ..tension t.. cycle; +fet_endchar; + + +fet_beginchar ("Numeral 4", "four"); + save alpha, beta, gamma; + + set_char_box (0, 4/5 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = 0; + calc_kuulleke (3/2 thick, alpha); + + z1r = (w - 3/4 thick, height); + z5 = (thin, 1/4 height + thin); + + beta = angle (z3r - z5); + + penpos6 (thin, -90); + z6l = z5; + + penpos7 (thin, -90); + y7 = y6; + x7 = w - 1/2 thin; + + penpos8 (thin, -alpha); + z8r = z5; + + penlabels (range 1 thru 8); + + gamma = angle (length (z1r - z1), 2 kuulleke); + + fill z2r{dir (alpha - gamma)} + .. z4 + .. {dir (alpha + gamma)}z3l + .. {dir (180 + beta)}z3r + -- z8r + -- z7l{right} + .. {left}z7r + -- z6r{left} + ..tension 0.8 and 2.. z8l{dir (beta)} + .. {up}z2l + .. cycle; + + clearxy; + + alpha := beta; + calc_kuulleke (thick, alpha); + + z1r = (w - 3/4 thick, height - (3/2 thin) / cosd (alpha)); + + penpos5 (thick, 0); + z5 = (x1, foot_top); + + gamma := angle (length (z1r - z1), 2 kuulleke); + + fill z2r{dir (alpha - gamma)} + .. z4 + .. {dir (alpha + gamma)}z3l + .. {down}z3r + -- z5r + -- z5l + -- z2l{up} + .. cycle; + + penlabels (1, 2, 3, 4, 5); + + draw_foot (x5); +fet_endchar; + + +fet_beginchar ("Numeral 5", "five"); + save alpha, beta, gamma, delta; + save inner_t, outer_t; + save pat; + path pat; + + set_char_box (0, 27/40 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = 0; + calc_kuulleke (w - thin, alpha); + + z1 = (w / 2 + 1/8 thick, h); + + penpos5 (thin, 0); + z5l = (x1l, h - 15/16 thick); + + penpos6 (hair, 90 - 45); + z6 = z5r + 1/2 hair * dir (-45); + + penpos7 (thin, 0); + z7l = (x1l, h / 2 + thin - hair); + + penlabels (range 1 thru 7); + + gamma = angle (length (z1r - z1), 2 kuulleke); + + pat := z2r{dir (alpha - gamma)} + .. z4 + .. {dir (alpha + gamma)}z3l + .. z3r{dir (-135)} + .. {left}z6r + .. {down}z6l + -- z7r{down} + .. {up}z7l + -- z2l{up} + .. cycle; + + beta = 45; + delta = 180 + beta + 10; + z8r = (x7r, y7r - 1/16 thick + thin); + z8l = directionpoint dir (delta) of + subpath (6, 7) of pat; + + % include intersection point to improve overlap removal + fill subpath (0, 6) of pat + .. z8l + .. subpath (7, length (pat)) of pat + .. cycle; + + penpos9 (thin, 90); + y9 = 10/16 [y5, y7]; + x9 = .36 [x8r, x10r]; + + penpos10 (thick, 0); + x10r = w + hair / 2; + y10r = 1/2 [y9r, y11r]; + + penpos11 (hair, -90); + y11r = 0; + x11r = .7 [0, x10l]; + + penlabels (range 8 thru 12); + + inner_t = 1.0; + outer_t = .85; + + fill z8r {dir (beta)} + .. z9r{right} + ..tension outer_t.. z10r{down} + .. number_flare_path (z11r, 180, -90, hair, flare, x11l, + .18 h, 0.06, 1.5, 1) + .. z11l{right} + ..tension inner_t.. z10l{up} + ..tension inner_t.. z9l{left} + .. z8l{dir (delta)} + -- cycle; +fet_endchar; + + +fet_beginchar ("Numeral 6", "six"); + draw_six; +fet_endchar; + + +fet_beginchar ("Numeral 7", "seven"); + save tolerance; + save alpha, beta, gamma, delta; + save bow; + save x_overshoot; + + path bow; + + set_char_box (0, 11/15 height# * widen - thin#, 0, height#); + overshoot_x = .75 thin; + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = -180; + + penpos1 (3/2 thick, 180 + alpha); + penpos2 (hair, 180 + alpha - 45); + penpos3 (hair, 180 + alpha + 45); + + z2 = z1l + (1/4 sqrt (2) * hair) * dir (alpha - 135); + z3 = z1r + (1/4 sqrt (2) * hair) * dir (alpha - 45); + z4 = z1 + kuulleke * dir (alpha - 90); + + z1l = (thin, 0); + + beta = 55; + penpos5 (thin, 90 + beta); + z5 = (w, h) + (1/2 sqrt (2) * thin) * dir (-135) + (overshoot_x, 0); + + gamma = angle (length (z1r - z1), 2 kuulleke); + delta = 12; + + pickup pencircle; + + fill z3l{dir (alpha - gamma)} + .. z4 + .. {dir (alpha + gamma)}z2r + .. z2l{dir (beta + delta)} + .. {dir (beta)}z5r + .. z5l{dir (180 + beta)} + .. {dir (delta - 90)}z3r + .. cycle; + + penlabels (1, 2, 3, 4, 5); + + alpha := -45 * widen; + + penpos11 (1/2 thick, 90); + z11 = (3/2 thin, h - (thick + thin) / 2); + + penpos13 (thin, 90 + beta); + z13 = z5; + + penpos12 (thick, 90 + alpha); + x12 = 1/2 [x11, x13] - 1/4 thick; + y12 = h - 15/16 thick + thin * widen; + + penpos14 (thin, 0); + z14l = (0, h - thin / 2); + + penpos15 (thin, 0); + z15l = (0, h / 2 + thin / 2); + + penpos16 (9/8 thick, 90); + z16r = (thin, y11r + 2/16 thick); + + tolerance := epsilon; + + % Find proper tension to exactly touch the x axis. + % Later on we directly use `bow'. + vardef f (expr t) = + bow := z11r{dir (beta)} + ..tension t.. {dir (alpha)}z12r; + ypart (directionpoint right of bow) > h + enddef; + + % the return value of `solve' is stored in a dummy variable + t = solve f (0.8, 1.2); + + fill bow + .. {dir (beta)}z13r + -- z13l{dir (180 + beta)} + .. {dir (180 + alpha)}z12l + .. {dir (180 + beta)}z11l + .. {down}z16l + -- z15r{down} + .. {up}z15l + -- z14l{up} + .. {down}z14r + -- z16r{down} + ..tension 1.5.. {dir (beta)}cycle; + + penlabels (range 11 thru 16); +fet_endchar; + + +fet_beginchar ("Numeral 8", "eight"); + save alpha, beta; + + set_char_box (0, 11/15 height# * widen, 0, height#); + + message "w:" & decimal w; + message "h:" & decimal h; + + alpha = 60; + beta = alpha - 15; + + z1 = (w / 2, h / 2 + thick / 8); + + penpos2 (14/8 thin, 0); + z2 = (w / 3, h / 2 + thin); + + penpos3 (3/2 thin, 0); + z3l = (0, h / 4 + thin / 2); + + penpos4 (hair, 90); + z4l = (x1, 0); + + penpos5 (thick, 90 + 90 + alpha); + z5 = z1 + w / 4 * dir (alpha - 90); + + penpos6 (thick, 90 + 90 + alpha); + z6 = z1 + (w / 4 - thin / 2) * dir (90 + alpha); + + penpos7 (hair, 90); + z7r = (x1 + .02 w, h); + + penpos8 (3/2 thin, 0); + z8r = (w - thin / 2, 3/4 h + thin / 2); + + penpos9 (13/8 thin, 0); + z9 = (2/3 w, h / 2); + + penlabels (range 1 thru 9); + + save t; + t = tense; + + fill z2r{dir (180 + beta)} + .. z3r{down} + .. z4r{right} + .. z5r{dir (90 + alpha)} + -- z6r{dir (90 + alpha)} + ..tension t.. z7r{right} + .. z8r{down} + .. {dir (180 + beta)}z9r + -- z9l{dir (beta)} + .. z8l{up} + .. z7l{left} + .. {dir (alpha - 90)}z6l + -- z5l{dir (alpha - 90)} + ..tension t.. z4l{left} + .. z3l{up} + .. {dir (beta)}z2l + -- cycle; +fet_endchar; + + +fet_beginchar ("Numeral 9", "nine"); + draw_six; +% xy_mirror_char; + + currentpicture := currentpicture scaled -1; + currentpicture := currentpicture shifted (w, h); +fet_endchar; + + +ligtable "3": + "3" kern 0.1 space#, + "0" kern 0.1 space#; + +ligtable "2": + "7" kern 0.15 space#; diff --git a/muse2/share/scoreglyphs/feta-original/feta-params.mf b/muse2/share/scoreglyphs/feta-original/feta-params.mf new file mode 100644 index 00000000..96d98628 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-params.mf @@ -0,0 +1,213 @@ +% +% feta-params.mf -- global parameters for both feta and parmesan fonts +% +% source file of the GNU LilyPond music typesetter +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +stafflines := 5; + +% +% The design size of a staff should really be the +% staff_space, but we use staffsize for historical reasons. +% + +staff_space# := staffsize# / (stafflines - 1); +staff_space_rounded# := staff_space#; + + +% +% Measuring on pocket scores turns out: stafflinethickness is +% largely independent on staff size, and generally about 0.5 pt. +% +% By request of WL, we tune down the blackness a little +% for increased contrast with beams. +% + +%% !! synchronize with paper.scm + +save fixed_line_thickness, variable_line_factor; +fixed_line_thickness + variable_line_factor * 5 pt# = 0.50 pt#; +fixed_line_thickness + variable_line_factor * 4.125 pt# = 0.47 pt#; + +stafflinethickness# := fixed_line_thickness + + variable_line_factor * staff_space#; +stafflinethickness_rounded# := stafflinethickness#; + +% +% The following tunes the general blackness of the glyphs. +% + +linethickness# := stafflinethickness#; %% 0.5 pt#; +linethickness_rounded# := linethickness#; + +% +% bigger puff_up_factor, relatively thicker stafflines. +% +% 20 pt = puff_up_factor 0 +% 10 pt = puff_up_factor 1 +% + +puff_up_factor = (linethickness# - 0.1 staff_space#) / (0.1 staff_space#); + + +stemthickness# := 1.3 stafflinethickness#; +stemthickness_rounded# := stemthickness#; +ledgerlinethickness# := 2 stafflinethickness#; +ledgerlinethickness_rounded# := ledgerlinethickness#; + +define_pixels (staff_space, stemthickness, stafflinethickness, + ledgerlinethickness, linethickness); +define_whole_pixels (staff_space_rounded); +define_whole_blacker_pixels (stemthickness_rounded); +define_whole_vertical_blacker_pixels (stafflinethickness_rounded, + ledgerlinethickness_rounded, + linethickness_rounded); + +if ledgerlinethickness_rounded > 2 stafflinethickness_rounded: + ledgerlinethickness_rounded := 2 stafflinethickness_rounded; +fi; + +% +% Because of the engraving/stamping process, no traditional +% characters have sharp edges and corners. +% The following variable controls the amount of `roundness'. +% +% This is not a meta variable: it is related to absolute sizes. +% +% FIXME: According to [Wanske], only outside corners should be round +% I don't think we do this anywhere -- jcn +% + +blot_diameter# = .40 pt#; +if (blot_diameter# * hppp) < 1: + blot_diameter# := 1 / hppp; +fi +if (blot_diameter# * vppp) < 1: + blot_diameter# := 1 / vppp; +fi + +define_pixels (blot_diameter); + + +% +% symmetry +% -------- +% +% Some glyphs have to be positioned exactly between stafflines (clefs, +% note heads). This needs some care at lower resolutions. +% +% Most glyphs use the staffline thickness and the space between two +% staff lines as the fundamental parameters. The latter is the distance +% between the middle of one staff line to the middle of the next. To +% say it differently, the value `staff_space' is the sum of one staff line +% thickness and the whitespace between two adjacent staff lines. +% +% Normally, feta's vertical origin for glyphs is either the middle +% between two staff lines or the middle of a staff line. For example, the +% lower edge of the central staff line is at the vertical position +% `-<staffline thickness> / 2', and the upper edge at +% `<staffline thickness> / 2'. Here we need a value rounded to an integer +% (the feta code uses `stafflinethickness_rounded' for that purpose). +% +% If we have an odd number of pixels as the staffline thickness, Metafont +% rounds `-stafflinethickness_rounded / 2' towards zero and +% `stafflinethickness_rounded / 2' towards infinity. Example: `round -1.5' +% yields -1, `round 1.5' yields 2. The whitespace between staff lines is +% handled similarly. If we assume that stafflinethickness_rounded is odd, +% we have the following cases: +% +% o The glyph is centered between three stafflines or five stafflines +% (clef, `c' meter). We have this: +% +% ___________ a +% ___________ 1 +% ___________ a +% +% whitespace +% +% ___________ a +% ...... ___________ 1 .................. x axis +% ___________ a +% +% whitespace +% +% ___________ a +% ___________ 1 +% ___________ a +% +% As can be seen, we get symmetry if we split staff lines into two +% equal parts `a' and a pixel line with thickness 1. Consequently, we +% use the following algorithm: +% +% . Decrease the height `h' by 1 temporarily. +% +% . Compute the path for the upper half of the glyph. +% +% . Mirror the path at the x axis. +% +% . Shift the upper half one pixel up and connect it with the lower path. +% +% . Restore height and decrease `d' by 1. +% +% o The glyph is centered between two or four staff lines, and the origin is +% the middle of the whitespace. Assuming that the the whitespace consists +% of an odd number of pixels, we have this: +% +% ----------- +% b +% 1 +% b +% ___________ +% b +% .................. 1 ................. x axis +% b +% ___________ +% b +% 1 +% b +% ___________ +% +% For symmetrical glyphs, this leads to a similar algorithm as above. +% Glyphs which can't be constructed from an upper and lower part need +% to be handled differently, namely to shift up the vertical center by +% half a pixel: +% +% ___________ +% b +% +% 0.5 +% .................. 0.5 ................ x axis +% +% b +% ___________ +% + +feta_eps := 0; +feta_shift := 0; +feta_space_shift := 0; + +% Use this for paths with a slant of 45 degrees to assure that +% the middle point of a penpos gets covered. +pair feta_offset; +feta_offset := (0, 0); + +if known miterlimit: + pickup nullpen; +else: + feta_eps := eps; + + if odd stafflinethickness_rounded: + feta_shift := 1; + fi; + + if odd (staff_space_rounded - stafflinethickness_rounded): + feta_space_shift := 1; + fi; + + feta_offset := (0.5, 0.5); + + pickup pencircle scaled 1; +fi; + +feta_fillpen := savepen; diff --git a/muse2/share/scoreglyphs/feta-original/feta-pendaal.mf b/muse2/share/scoreglyphs/feta-original/feta-pendaal.mf new file mode 100644 index 00000000..fded9ecb --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-pendaal.mf @@ -0,0 +1,348 @@ +% -*- Fundamental -*- (emacs-20 mf mode mucks +% feta-pendaal.mf -- piano pedal markings +% +% part of LilyPond's pretty-but-neat music font +% +% source file of the Feta (not the Font-En-Tja) music font +% +% (c) 2000--2009 Jan Nieuwenhuizen <janneke@gnu.org> +% +% Voor Cup + +% Kerning +% +% Pe = -0.034 pedalh == -0.07 staff-space +% ed = -0.27 pedalh == -0.53 staff-space + + +fet_begingroup ("pedal"); + +pedalpha = 40; +pedbeta = 25; + +penh# = 0.7 linethickness#; +penw# = 2 penh# + 0.14 staff_space#; +define_pixels (penh, penw); + +pedalh# = 2 staff_space#; +pedalbh# = 4/7 pedalh#; +define_pixels (pedalh, pedalbh); + + +fet_beginchar ("Pedal asterisk", "*"); + save bulb, p, radius, thin, inner_r; + path pat; + + set_char_box (0, 7/9 pedalh#, 0, pedalh#); + + z0 = (1/2 w, h - 1/2 w); + + thin = 0.8 linethickness; + + bulb + 2 radius = w; + 0.9 thin + bulb = (radius * pi * 2) / 8; + + pickup pencircle scaled penh; + + penpos1 (bulb, 180); + penpos2 (bulb, 0); + penpos3 (thin, 0); + + z1 = z0 + (0, radius); + z2 = z1; + + inner_r = .45 radius; + + z4l = z0 + inner_r * dir (90 + 360/16); + z4r = z0 + inner_r * dir (90 - 360/16); + + z4 = .5 [z4l, z4r]; + z3 = .75 [z1, z4]; + + penlabels (0, 1, 2, 3, 4); + + pat := z3r{up} + .. z1l{up} + .. z2l{down} + .. z3l{down} + .. z4l{dir (180 + 360/16)}; + for i = 1 upto 7: + pat := pat + .. ((z3r{up} + .. z1l{up} + .. z2l{down} + .. z3l{down} + .. z4l{dir (180 + 360/16)}) + rotatedaround (z0, 360/8 i)); + endfor; + + pat := pat + .. cycle; + fill pat; + + pickup pencircle scaled (7/8 inner_r); + + undrawdot z0; +fet_endchar; + + +%% ugh. rounded corners! + +fet_beginchar ("Pedal dash", "M"); + save dash_thickness; + + dash_thickness# := penw#; + define_whole_vertical_blacker_pixels (dash_thickness); + + set_char_box (0, 3 penw#, 0, pedalbh#); + + penpos1 (dash_thickness, 60); + penpos2 (dash_thickness, 60); + + z1l = (0, vround (2/3 h - 1/2 penw)); + z2r = (w, vround (y1l + 1.2 penw)); + + penlabels (1, 2, 3); + + penstroke z1e{dir 40} + ..tension 1.2.. z2e{dir 40}; +fet_endchar; + + +fet_beginchar ("Pedal dot", "."); + set_char_box (0, penw#, 0, penw#); + + pickup pencircle scaled penw; + + drawdot (hround (1/2 penw), vround (1/2 penw)); +fet_endchar; + + +def draw_pedal_P (expr show_labels) = +begingroup; + clearxy; + + penpos1 (hround penh, 0); + penpos2 (penw, 55); + penpos3 (penw, pedalpha); + penpos4 (1.2 penh, -pedalpha); + penpos5 (penh, -pedalpha); + penpos6 (penh, 180 - pedalpha); + penpos7 (penh, 180 - pedalpha); + penpos8 (penh, 90); + penpos9 (4/3 penw, 50); + penpos10 (1.4 penw, 50); + penpos11 (penh, 90 + pedalpha); + + z1r = (hround 0.6 w, h); + x2l = hround (x1l - penw) + xpart feta_offset; + y2 = vround (0.7 h) + ypart feta_offset; + x3r = hround (x2l + 2 penw); + y3r = 0.4 h; + z4l = z5r + 1/4 (z3r - z5r); + x5 = 1/4 w; + y5r = 0; + z6 = z5; + z7l = z6r + 1/3 (z8r - z6r); + z8r = z5r + 3/5 (z3r - z5r); + x9l = x10l - penh; + y9l = 1/4 penh; + x10l = w - tand (90 - pedalpha) * y11l; + y10l = 1/4 penh; + x11l = w; + y11 = 1/5 h; + + % don't stick out at the top + z1' = round (0.9 [z2, z1]) + (xpart feta_offset, 0); + penpos1' (penh, 0); + + % shift start point of pen stroke to avoid overlapping contours + z8'l = z8l; + y8'r = y8r; + z8'r = z8l + whatever * (z3r - z8l); + + penpos12 (hround penh, 0); + penpos13 (penw, -90 - pedbeta); + penpos14 (vround penh, 90); + penpos15 (penw, -90 + pedbeta); + penpos16 (penh, 180 + pedbeta); + + z12r = (hround (5/9 x1 + 1/2 hround penh), y2); + z13l = (1/2 x12r, y15r); + z14r = z1r; + z15l = (1/2 [x16, w], y2l + 0.5 penw); + x16 = 1/4 [x1, w]; + y16r = y2r; + + % We now do a correction to `center' the stem horizontally. While + % this is not the most elegant solution, it is definitely the + % easiest... + + save horz_corr; + horz_corr = 1/5 [x12, x16] - x2l; + x2 := x2 + horz_corr; + x2l := x2l + horz_corr; + x2r := x2r + horz_corr; + + penstroke z1'e + ..tension 2.5.. z2e + ..tension 1.5.. z3e + ..tension 2.5.. {dir (225)}z4e; + + soft_end_penstroke z8'e{right} + ..tension 1.5.. z9e{dir (-pedalpha)} + .. z10e + ..tension 2.5.. z11e; + + fill z4r{dir (225)} + ..tension 1.5.. z5r{left} + .. z6r + ..tension 1.5.. z7r + ..tension 1.5.. z8r{right} + -- cycle; + + soft_penstroke z12e{down} + ..tension 1.1.. z13e{dir (180 - pedbeta)} + ..tension 1.1.. z14e{right} + ..tension 1.1.. z15e{dir (180 + pedbeta)} + ..tension 1.1.. z16e{dir (90 + pedbeta)}; + + if show_labels = 1: + penlabels (range 1 thru 16); + penlabels (1', 8'); + fi; +endgroup; +enddef; + + +def draw_pedal_d (expr show_labels) = +begingroup; + clearxy; + + penpos1 (vround penh, -10 - 90); + penpos2 (hround penw, 190); + penpos3 (vround (2 penh), 90); + penpos4 (hround (3/4 penw), 0); + penpos5 (penh, -70); + + x1r = 0; + y1l = h; + z2 = (w - 1/2 hround penw, 1/2 pedalbh + penh); + z4l = (hround (1/3 w), 1/2 pedalbh); + z5l = (2/3 w, pedalbh); + z3l = (hround x5l, 0); + + if show_labels = 1: + penlabels (1, 2, 3, 4, 5); + fi; + + soft_start_penstroke z1e{dir (-10)} + ..tension 1.1.. z2e{dir (-90 + 10)} + ..tension 1.1.. z3e{left} + ..tension 1.1.. z4e{up} + ..tension 1.1.. z5e{dir (-70 + 90)}; +endgroup; +enddef; + + +def draw_pedal_e (expr show_labels) = +begingroup; + clearxy; + + penpos1 (penh, pedalpha - 90); + penpos2 (penh, pedalpha - 90); + penpos3 (3/5 penw, pedalpha); + penpos4 (1.2 penh, 90 + pedalpha); + penpos5 (2/3 penw, 180); + penpos6 (penw, 180 + pedalpha); + penpos7 (2/3 penw, -90 - 20); + penpos8 (penh, pedalpha - 90); + + z1l = (0, 1/5 pedalh); + % this helps to make the path go through z2 at low resolutions + z2 = round (z1 + dir pedalpha * penw) + feta_offset; + z3 = (3/5 w, 8/9 h); + z4 = (2/9 w, y3); + x4r := hround x4r; + x5r = 0; + y5 = y2; + x6 = 3/8 w; + y6r = 1/2 penh; + z7l = (x6l + penh, y6l); + x8r = w; + y8 = 1/5 pedalh; + + soft_penstroke z1e + -- z2e{z2 - z1} + ..tension 1.1.. z3e + ..tension 1.05.. z4e + ..tension 1.1.. z5e + ..tension 1.5.. z6e{dir - pedalpha} + ..tension 1.1.. z7e + ..tension 2.5.. z8e; + + if show_labels = 1: + penlabels (range 1 thru 8); + fi; +endgroup; +enddef; + + +fet_beginchar ("Pedal P", "P"); + set_char_box (0, 5/6 pedalh#, 0, pedalh#); + + draw_pedal_P (1); +fet_endchar; + + +fet_beginchar ("Pedal d", "d"); + set_char_box (0, 2/3 pedalh#, 0, 7/8 pedalh#); + + draw_pedal_d (1); +fet_endchar; + + +fet_beginchar ("Pedal e", "e"); + set_char_box (0, 2/5 pedalh#, 0, pedalbh#); + + draw_pedal_e (1); +fet_endchar; + + +fet_beginchar ("Pedal Ped", "Ped"); + P_width# = 5/6 pedalh#; + e_width# = 2/5 pedalh#; + d_width# = 2/3 pedalh#; + define_pixels (P_width, e_width, d_width); + + e_height = pedalbh; + d_height = 7/8 pedalh; + + % Pe = -0.034 pedalh == -0.07 staff-space + % ed = -0.27 pedalh == -0.53 staff-space + Pe_kern# = -0.034 pedalh#; + ed_kern# = -0.27 pedalh#; + define_pixels (Pe_kern, ed_kern); + + w := hround d_width; + h := vround d_height; + draw_pedal_d (0); + currentpicture := currentpicture + shifted (hround (e_width + ed_kern), 0); + + w := hround e_width; + h := vround e_height; + draw_pedal_e (0); + currentpicture := currentpicture + shifted (hround (P_width + Pe_kern), 0); + + w := hround P_width; + h := vround pedalh; + draw_pedal_P (0); + + set_char_box (0, P_width# + Pe_kern# + e_width# + ed_kern# + d_width#, + 0, pedalh#); +fet_endchar; + + +fet_endgroup ("pedal"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-puntje.mf b/muse2/share/scoreglyphs/feta-original/feta-puntje.mf new file mode 100644 index 00000000..a24e3693 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-puntje.mf @@ -0,0 +1,26 @@ +% +% feta-puntje.mf -- a duration dot +% +% source file of the GNU LilyPond music typesetter +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> + +fet_begingroup ("dots"); + +save dot_diam; + +2 dot_diam# = staff_space# - stafflinethickness#; +define_whole_blacker_pixels (dot_diam); + +fet_beginchar ("duration dot", "dot"); + pickup pencircle scaled dot_diam; + + lft x0 = 0; + top y0 = vround (.5 dot_diam); + + drawdot z0; + + set_char_box (0, dot_diam#, .5 dot_diam#, .5 dot_diam#); +fet_endchar; + +fet_endgroup ("dots"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-schrift.mf b/muse2/share/scoreglyphs/feta-original/feta-schrift.mf new file mode 100644 index 00000000..5bb7c1ab --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-schrift.mf @@ -0,0 +1,1560 @@ +% -*- Fundamental -*- (emacs-20 mf mode mucks +% feta-schrift.mf -- implement scripts +% +% source file of the Feta (defintively not an abbreviation for Font-En-Tja) +% music font +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% Jan Nieuwenhuizen <janneke@gnu.org> +% + + +fet_begingroup ("scripts"); + +def draw_fermata = + save alpha, radius, crook_thinness, crook_fatness, dot_size; + save pat; + path pat; + + % [Wanske] and some Baerenreiter editions + % suggest about 80 degrees instead of a half-circle + alpha := 10; + + radius# = 1.25 staff_space#; + crook_thinness# = 1.5 linethickness#; + crook_fatness# = 0.25 staff_space# + 1.5 linethickness#; + + radius# + crook_fatness# / 2 = h#; + radius# + crook_thinness# / 2 = w#; + + set_char_box (w#, w#, crook_thinness# / 2, h#); + + define_pixels (radius, crook_thinness, crook_fatness); + + dot_size# = 8/6 crook_fatness#; + define_whole_blacker_pixels (dot_size); + + penpos1 (crook_thinness, 0); + penpos2 (crook_fatness, -90); + z1 = (-radius, 0); + z2 = (0, radius); + + pat := z2l{left} + .. z1l{dir (-alpha - 90)} + .. {dir (90 - alpha)}z1r + .. {right}z2r; + pat := pat + -- reverse pat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + fill pat; + + pickup pencircle scaled dot_size; + x4 = 0; + bot y4 = vround (-crook_thinness / 2); + drawdot z4; +enddef; + + +fet_beginchar ("fermata up", "ufermata"); + draw_fermata; + penlabels (1, 2, 4); +fet_endchar; + + +fet_beginchar ("fermata down", "dfermata"); + draw_fermata; + y_mirror_char; +fet_endchar; + + +def draw_short_fermata = + save fat_factor, thinness, dot_size; + save left_dist, right_dist, se, ne; + pair left_dist, right_dist, se, ne; + + set_char_box (staff_space#, staff_space#, 0, 2.2 staff_space#); + + dot_size# = 0.266 staff_space# + 2.666 linethickness#; + define_whole_blacker_pixels (dot_size); + + fat_factor = .11; + thinness = 1.5 linethickness; + + pickup pencircle scaled thinness; + + rt x2 = w; + lft x5 = -b; + bot y5 = 0; + top y3 = h; + y1 = y2 = y5; + + x3 = 0; + z1 - z4 = whatever * (charwd, -charht); + z4 = fat_factor [z3, z5]; + + ne = unitvector (z3 - z5); + se = unitvector (z2 - z3); + + left_dist = (ne rotated 90) * 0.5 thinness; + right_dist = (se rotated 90) * 0.5 thinness; + + fill bot z5{right} + .. (z5 - left_dist){ne} + -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint + ((z1 - right_dist) -- (z4 - right_dist))) + -- (z1 - right_dist){se} + .. bot z1{right} + -- bot z2{right} + .. (z2 + right_dist){-se} + -- (z3 + right_dist){-se} + .. top z3 + .. (z3 + left_dist){-ne} + -- (z5 + left_dist){-ne} + .. cycle; + + pickup pencircle scaled dot_size; + + x1 - 2 x6 = x2; + x6 := vround (x6); + bot y6 = -d; + + drawdot z6; +enddef; + +fet_beginchar ("short fermata up", "ushortfermata"); + draw_short_fermata; + labels (1, 2, 3, 4, 5, 6); +fet_endchar; + + +fet_beginchar ("short fermata down", "dshortfermata"); + draw_short_fermata; + xy_mirror_char; +fet_endchar; + + +def draw_long_fermata = + save stemthick, beamheight, dot_size, wd; + save pat; + path pat; + + wd# = 2.5 staff_space#; + stemthick = hround (1.5 linethickness); + beamheight = 0.3 staff_space + linethickness; + dot_size# = 0.266 staff_space# + 2.666 * linethickness#; + define_pixels (wd); + define_whole_blacker_pixels (dot_size); + + set_char_box (wd# / 2, wd# / 2, 0, 3/2 staff_space#); + + pickup pencircle scaled blot_diameter; + + top y1 = h; + lft x1 = -b; + + pat := top z1{left} + .. {down}lft z1; + + pickup pencircle scaled stemthick; + + x2 = -b + stemthick; + y2 = h - beamheight; + lft x3 = -b; + bot y3 = -d; + + pat := pat + -- lft z3 + .. bot z3 + .. rt z3 + -- z2; + pat := pat + -- reverse pat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + + fill pat; + + pickup pencircle scaled dot_size; + + x4 = 0; + bot y4 = -d; + + drawdot z4; +enddef; + + +fet_beginchar ("long fermata up", "ulongfermata"); + draw_long_fermata; + labels (1, 2, 3, 4); +fet_endchar; + + +fet_beginchar ("long fermata down", "dlongfermata"); + draw_long_fermata; + y_mirror_char; +fet_endchar; + + +def draw_very_long_fermata = + save ibeamheight, obeamheight; + save ihwd, ohwd, iht, oht; % inner/outer half_width/height + save stemthick, dot_size; + save opat, ipat; + path opat, ipat; + + ihwd# = 1.0 staff_space#; + ohwd# = 1.5 staff_space#; + iht# = 0.9 staff_space#; + oht# = 1.6 staff_space#; + define_pixels (ihwd, ohwd, iht, oht) + + stemthick = hround (1.5 linethickness); + ibeamheight# = 0.3 staff_space#; + obeamheight# = 0.5 staff_space#; + define_pixels (ibeamheight, obeamheight); + + dot_size# = (iht# - ibeamheight#) * 8/10; + define_whole_blacker_pixels (dot_size); + + set_char_box (ohwd#, ohwd#, 0, oht#); + + pickup pencircle scaled blot_diameter; + + top y1 = oht; + lft x1 = -ohwd; + top y11 = iht; + lft x11 = -ihwd; + + opat := top z1{left} + .. {down}lft z1; + ipat := top z11{left} + .. {down}lft z11; + + pickup pencircle scaled stemthick; + + x2 = -ohwd + stemthick; + y2 = oht - obeamheight; + lft x3 = -ohwd; + bot y3 = 0; + x12 = -ihwd + stemthick; + y12 = iht - ibeamheight; + lft x13 = -ihwd; + bot y13 = 0; + + opat := opat + -- lft z3 + .. bot z3 + .. rt z3 + -- z2; + opat := opat + -- reverse opat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + ipat := ipat + -- lft z13 + .. bot z13 + .. rt z13 + -- z12; + ipat := ipat + -- reverse ipat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + + fill opat; + fill ipat; + + pickup pencircle scaled dot_size; + + x4 = 0; + bot y4 = -d; + + drawdot z4; +enddef; + + +fet_beginchar ("very long fermata up", "uverylongfermata"); + draw_very_long_fermata; + labels (1, 2, 3, 11, 12, 13, 4); +fet_endchar; + + +fet_beginchar ("very long fermata down", "dverylongfermata"); + draw_very_long_fermata; + y_mirror_char; +fet_endchar; + + +% +% Thumbs are used in cello music. +% TODO : thumbs should look like the finger-font and should be placed in +% the same way in the score. +% + +fet_beginchar ("Thumb", "thumb"); + save thin, height, width, thick, depth; + height# = 5/4 width#; + height# = staff_space#; + depth# = 1.6 (height# / 2); + + set_char_box (width# / 2, width# / 2, depth#, height# / 2); + + define_pixels (height, width); + + thin = .6 linethickness + 0.06 staff_space; + 2 thick + 0.5 (height - 2 thin) = width; + + penpos1 (thick, 0); + penpos2 (thin, 90); + penpos3 (thick, 180); + penpos4 (thin, 270); + z1r = (w, 0); + z2r = (0, h); + z3r = (-w, 0); + z4r = (0, -h); + + penlabels (1, 2, 3, 4); + + penstroke z1e{up} + .. z2e{left} + .. z3e{down} + .. z4e{right} + .. cycle; + + save brush_thick; + y5 = -d + brush_thick / 2; + brush_thick = 0.9 thick; + x5 = 0; + + labels (5); + + draw_brush (z4r, 1.4 thin, z5, brush_thick); +fet_endchar; + + +% +% `\accent' is TeX reserved. +% + +def draw_accent (expr bottom_left, top_right, thickness, diminish) = + save thinning_start; + thinning_start = 0.4; + pickup pencircle scaled thickness; + + lft x1 = xpart bottom_left; + top y1 = ypart top_right; + lft x6 = xpart bottom_left; + bot y6 = ypart bottom_left; + + rt z4 = (xpart top_right, (ypart top_right + ypart bottom_left) / 2); + x5 = x3 = thinning_start [xpart top_right, xpart bottom_left] + - linethickness + 0.1 staff_space; + z3 = whatever [z1, z4]; + z5 = whatever [z6, z4]; + + penpos1 (thickness, angle (z3 - z1) + 90); + penpos3 (thickness, angle (z3 - z1) + 90); + penpos4 (thickness, 90); + penpos5 (thickness, angle (z6 - z5) + 90); + penpos6 (thickness, angle (z6 - z5) + 90); + + x4 - x7 = diminish * thickness; + y7 = y4; + + fill z1l + -- z3l + -- z7 + -- z5l + -- z6l + .. lft z6{down} + .. bot z6 + .. z6r + -- z4l + ..tension 0.8.. rt z4 + ..tension 0.8.. z4r + -- z1r + .. top z1 + .. lft z1{down} + .. cycle; +enddef; + + +fet_beginchar ("> accent", "sforzato"); + set_char_box (.9 staff_space#, .9 staff_space#, + .5 staff_space#, .5 staff_space#); + + draw_accent ((-w, -d), (w, h), + 0.05 staff_space + linethickness, 0.7); + penlabels (1, 3, 4, 5, 6); + labels (7); +fet_endchar; + + +fet_beginchar ("espr", "espr"); + set_char_box (1.9 staff_space#, 1.9 staff_space#, + .5 staff_space#, .5 staff_space#); + + draw_accent ((w - 1.78 staff_space, -d), (w, h), + 0.05 staff_space + linethickness, 0.6); + addto currentpicture also currentpicture xscaled -1; +fet_endchar; + + +fet_beginchar ("staccato dot", "staccato"); + save radius; + radius# = 0.20 * staff_space#; + define_whole_pixels (radius); + + pickup pencircle scaled 2 radius; + drawdot (0, 0); + + set_char_box (radius#, radius#, radius#, radius#); +fet_endchar; + + +def draw_staccatissimo = + save radius, height; + height# = .8 staff_space#; + radius# = linethickness# + .1 staff_space#; + define_whole_blacker_pixels (radius); + define_pixels (height); + + draw_brush ((0, 0), linethickness, (0, height), 2 radius); + + set_char_box (radius#, radius#, + blot_diameter# / 2, height# + radius#); +enddef; + + +fet_beginchar ("staccatissimo/martellato up", "ustaccatissimo"); + draw_staccatissimo; +fet_endchar; + + +fet_beginchar ("staccatissimo/martellato down", "dstaccatissimo"); + draw_staccatissimo; + y_mirror_char; +fet_endchar; + + +fet_beginchar ("portato/single tenuto", "tenuto"); + save thick; + thick# = 1.6 linethickness#; + define_whole_blacker_pixels (thick); + + set_char_box (.6 staff_space#, .6 staff_space#, + thick# / 2, thick# / 2); + + draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick); +fet_endchar; + + +def draw_portato = + save thick, dot_size; + thick# = 1.4 linethickness#; + dot_size# = 2.4 linethickness# + 0.08 staff_space#; + define_whole_blacker_pixels (thick, dot_size); + + set_char_box (.6 staff_space#, .6 staff_space#, + thick# / 2, .5 staff_space# + .5 dot_size#); + + draw_rounded_block ((-b, -thick / 2), (w, thick / 2), thick); + + pickup pencircle scaled dot_size; + drawdot (0, h); +enddef; + + +fet_beginchar ("portato/tenuto with staccato", "uportato"); + draw_portato; +fet_endchar; + + +fet_beginchar ("portato/tenuto with staccato", "dportato"); + draw_portato; + y_mirror_char +fet_endchar; + + +def draw_marcato = + save fat_factor, thinness; + save left_dist, right_dist, ne, se; + pair left_dist, right_dist, ne, se; + + set_char_box (staff_space# / 2, staff_space# / 2, + 0, 1.1 staff_space#); + + fat_factor = .3; + thinness = linethickness; + + pickup pencircle scaled thinness; + + rt x2 = w; + lft x5 = -b; + bot y5 = 0; + top y3 = h; + y1 = y2 = y5; + + x3 =0; + z1 - z4 = whatever * (charwd, -charht); + z4 = fat_factor [z3, z5]; + + ne = unitvector (z3 - z5); + se = unitvector (z2 - z3); + + left_dist = (ne rotated 90) * 0.5 thinness; + right_dist = (se rotated 90) * 0.5 thinness; + + fill bot z5{right} + .. (z5 - left_dist){ne} + -- (((z5 - left_dist) -- (z3 - left_dist)) intersectionpoint + ((z1 - right_dist) -- (z4 - right_dist))) + -- (z1 - right_dist){se} + .. bot z1{right} + -- bot z2{right} + .. (z2 + right_dist){-se} + -- (z3 + right_dist){-se} + .. top z3 + .. (z3 + left_dist){-ne} + -- (z5 + left_dist){-ne} + .. cycle; +enddef; + + +fet_beginchar ("marcato up", "umarcato"); + draw_marcato; + labels (1, 2, 3, 4, 5); +fet_endchar; + + +% +% The down marcato char (not very much used). +% Contrary to what some MF/TeX `gurus' believe +% it is *point*-symmetric with the "up" version +% + +fet_beginchar ("marcato down", "dmarcato"); + draw_marcato; + xy_mirror_char; +fet_endchar; + + +% +% used in french horn music todo +% +% TODO: too light at 20pt +% + +fet_beginchar ("open (unstopped)", "open"); + save thin, height, width, thick; + + height# = 5/4 width#; + height# = staff_space#; + thin = .6 linethickness + 0.06 staff_space; + + set_char_box (width# / 2, width# / 2, height# / 2, height# / 2); + + define_pixels (width, height); + + 2 thick + 0.6 (height - 2 thin) = width; + + penpos1 (thick, 0); + penpos2 (thin, 90); + penpos3 (thick, 180); + penpos4 (thin, 270); + z1r = (w, 0); + z2r = (0, h); + z3r = (-w, 0); + z4r = (0, -h); + + penlabels (1, 2, 3, 4); + + penstroke z1e{up} + .. z2e{left} + .. z3e{down} + .. z4e{right} + .. cycle; +fet_endchar; + + +fet_beginchar ("plus (stopped)", "stopped"); + save hthick, vthick, size, outer_hsize, outer_vsize; + + hthick# = vthick# = 2 linethickness#; + size# = 1.1 staff_space#; + define_whole_blacker_pixels (vthick); + define_whole_vertical_blacker_pixels (hthick); + + set_char_box (size# / 2, size# / 2, size# / 2, size# / 2); + + outer_hsize = hround ((b + w - vthick) / 2); + outer_vsize = vround ((h + d - hthick) / 2); + w := b := (2 outer_hsize + vthick) / 2; + h := d := (2 outer_vsize + hthick) / 2; + + draw_rounded_block ((-b, -d + outer_vsize), + (w, -d + outer_vsize + hthick), hthick); + draw_rounded_block ((-b + outer_hsize, -d), + (-b + outer_hsize + vthick, h), vthick); +fet_endchar; + + +fet_beginchar ("Upbow", "upbow"); + save ht, wd, thick; + + thick = 1.4 linethickness; + wd# = 1.3 staff_space#; + ht# = 1.6 wd#; + + set_char_box (wd# / 2, wd# / 2, 0, ht#); + + draw_accent ((-h, -w), (0, w), thick, 0.9); + currentpicture := currentpicture rotated -90; +fet_endchar; + + +fet_beginchar ("Downbow", "downbow"); + save stemthick, beamheight, wd; + save pat; + path pat; + + wd# = 1.5 staff_space#; + define_pixels (wd); + + stemthick = hround (1.2 linethickness); + + set_char_box (wd# / 2, wd# / 2, 0, 4/3 staff_space#); + + beamheight = 4/10 h; + + pickup pencircle scaled blot_diameter; + + top y1 = h; + lft x1 = -b; + + pat := top z1{left} + .. {down}lft z1; + + pickup pencircle scaled stemthick; + + x2 = -b + stemthick; + y2 = h - beamheight; + lft x3 = -b; + bot y3 = -d; + + pat := pat + -- lft z3 + .. bot z3 + .. rt z3 + -- z2; + pat := pat + -- reverse pat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + + fill pat; + + labels (1, 2, 3); +fet_endchar; + +% +% Inspired by a computer-set version of Auf dem Strom by Baerenreiter. +% + +def draw_turn = + save thin, thick, ball_diam, darkness; + save wd, ht, thick_nibangle, ball_nib_thick; + save turndir; + pair turndir; + + wd# = 35/16 staff_space#; + ht# = 18/17 staff_space#; + darkness = 0.3 linethickness + 0.09 staff_space; + + set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2); + + thick_nibangle = 60; + thick = 3 darkness; + thin = darkness; + ball_nib_thick = 2.7 darkness; + ball_diam = ball_nib_thick + (h - ball_nib_thick) / 10; + + x3l = w; + y3 = 0; + y4l = h; + x4 = x2; + x2l = w / 2; + y2l = -d; + z1 = (0,0); + + penpos1 (1.1 thick, thick_nibangle); + penpos2 (thick, thick_nibangle); + penpos3 (thin, 180); + penpos4 (ball_nib_thick, -90); + + path swoosh, ploop; + swoosh := z1l{curl 0} + .. z2l + .. z3l{up} + .. {left}z4l + -- z4r + .. z3r{down} + .. z2r{left}; + fill swoosh + .. swoosh scaled -1 shifted (-feta_eps, -feta_eps) + .. cycle; + + x5r = x4; + y5r = y4l - ball_diam / 2; + z6r = z5r; + + penpos5 (1.6 ball_diam / 2, 10); + penpos6 (ball_diam / 2, 150); + + ploop := z4l{left} + .. z5l + .. z6l + -- cycle; + fill ploop; + fill ploop scaled -1 shifted (-feta_eps, -feta_eps); +enddef; + + +fet_beginchar ("Reverse turn", "reverseturn"); + draw_turn; + currentpicture := currentpicture yscaled -1; +fet_endchar; + + +fet_beginchar ("Turn", "turn"); + draw_turn; + penlabels (1, 2, 3, 4, 5, 6, 7); +fet_endchar; + + +% +% Inspired by a (by now) PD edition of Durand & C'ie edition of +% Saint-Saens' Celloconcerto no. 1 +% +% FIXME take out hardcoded vars. +% FIXME the two loops on the `t' should be smoother (and the left one bigger). +% FIXME generic macros for serifs: top of the t and bottom of r +% + +fet_beginchar ("Trill (`tr')", "trill"); + save start_nib_angle, ascender_extra, ex, hair_thick, fatness; + save slant, t_fatness, r_fatness, kerning, t_overshoot; + save uitschieter, bulb_size, krul_ang; + save u, v; + + ascender_extra# = 1/2 ex#; + ascender# = ascender_extra# + ex#; + ex# = 1.4 staff_space#; + kerning# = 0.6 ex#; + start_nib_angle = 20; + bulb_size = 0.8; + define_pixels (ex, ascender_extra, ascender, kerning); + + t_overshoot = 0.03 ex; + fatness = 12/40 ex; + t_fatness = 0.78 fatness; + t_width = 1.9 t_fatness; + r_fatness = 0.78 fatness; + uitschieter = 0.48 ex; + hair_thick = linethickness; + r_flare = .5 hair_thick + 0.25 r_fatness; + r_width = 2 r_fatness + 0.25 kerning; + slant = .2; + + local_copy (transform)(currenttransform); + currenttransform := currenttransform slanted slant + shifted (-staff_space, 0); + + set_char_box (.85 staff_space#, .85 staff_space#, 0, ascender#); + + y1 = ascender; + + % try to position in such a way that the center is the visual + % center + + x1l = 0.2 staff_space; + x1r - x1l = t_fatness; + penpos1 (start_nib_wid, start_nib_angle); + + z2 = (x1, 7/18 ex); + penpos2 (start_nib_wid, start_nib_angle); + + z3l = (x2l + 0.5 t_width, - t_overshoot); + + z4l = (x2l + t_width, 0.23 ex); + penpos4 (whatever, 180); % 200 + x4l - x4r = hair_thick; + + x3r = 0.5 [x4r, x2r]; +% 1.7 [x3l, x3r] = x4r; + y3r - y3l = 0.6 t_fatness; + + save krul_p; + path krul_p; + + krul_ang = 32; + + pickup pencircle scaled hair_thick; + + z5 = (x2l + t_fatness / 2, 2/3 ex); + lft x6 = x2l - uitschieter; + y6 = y5; % - 1/20 ex; + z7 = z5 + whatever * dir krul_ang; + up_angle = krul_ang; % = angle (z7-z5) + x7 = 5/10 kerning + x5; + + krul_p := z4{up} + ..tension 0.98.. z5 + .. z6 + .. z5{z7 - z5} + -- z7; + + z4' = point 0.85 of krul_p; + penpos4' (hair_thick, angle (direction 0.85 of krul_p) + 90); + + % the body of the `t' and the bottom loop + fill z1r{dir (angle (z1l - z1r) + 30)} + .. z1l{-dir (angle (z1r - z1l) - 45)} + -- z2l{down} + ..tension (1 + .5 slant).. z3l{right} + .. z4l{up} + .. z4'l{direction 0.85 of krul_p} + -- z4'r{-direction 0.85 of krul_p} + .. z4r{down} + .. z3r{left} + ..tension (1.5 + .7 slant).. z2r{up} + -- cycle; + + z5' = point 1.1 of krul_p; + penpos5' (hair_thick, angle (direction 1.1 of krul_p) + 90); + z5'' = point 1.5 of krul_p; + penpos5'' (hair_thick, angle (direction 1.5 of krul_p) + 90); + z5''' = point 1.8 of krul_p; + penpos5''' (hair_thick, angle (direction 1.8 of krul_p) + 90); + z6 = point 2 of krul_p; + penpos6 (hair_thick, angle (direction 2 of krul_p) + 90); + z6' = point 2.3 of krul_p; + penpos6' (hair_thick, angle (direction 2.3 of krul_p) + 90); + z6'' = point 2.6 of krul_p; + penpos6'' (hair_thick, angle (direction 2.6 of krul_p) + 90); + z6''' = point 2.9 of krul_p; + penpos6''' (hair_thick, angle (direction 2.9 of krul_p) + 90); + penpos7 (hair_thick, up_angle + 90); + z7' = point 3.2 of krul_p; + penpos7' (hair_thick, angle (direction 3.2 of krul_p) + 90); + + % the left loop + penstroke z5'e{direction 1.1 of krul_p} + .. z5''e{direction 1.5 of krul_p} + .. z5'''e{direction 1.8 of krul_p} + .. z6e{direction 2 of krul_p} + .. z6'e{direction 2.3 of krul_p} + .. z6''e{direction 2.6 of krul_p} + .. {direction 2.9 of krul_p}z6'''e; + + y9 = 3/4 ex; + x9 = x1 + kerning; + penpos9 (r_fatness, 0); + + x10 = x9; + y10 = -0.3 linethickness; + penpos10 (r_fatness, 0); + + penpos11 (hair_thick, -4); + z11r = z9r; + + z13l = (x9l + r_width, y11 - linethickness); + penpos13 (r_flare, 180); + + z15 = z13r - (bulb_size * r_fatness, 0); + z14 = 0.5 [z13l, z15] - (0, bulb_size * r_fatness); + + save before, after; + path before, after; + before := z13l{up} + .. {down}z11l; + after := z9r{up} + .. z7r{z7' - z7} + -- z7'r; + (u, v) = before intersectiontimes after; + + save before_bulb, after_bulb; + path before_bulb, after_bulb; + before_bulb := z9r{up} + ..tension 0.94.. z13r{down}; + after_bulb := z13l{up} + ..tension 1.06.. z15{down}; + (u_bulb, v_bulb) = before_bulb intersectiontimes after_bulb; + + % the connection between `t' and `r', the body of the `r', + % and the bulb + fill z7'l + -- z7l{z7 - z7'} + .. z9l{down} + -- simple_serif (z10l, z10r, -30) + -- z9r{up} + .. subpath (0, u_bulb) of before_bulb + .. subpath (v_bulb, infinity) of after_bulb + .. z14 + .. z13l{up} + .. subpath (0, u) of before + .. subpath (v, infinity) of after + -- cycle; + + penlabels (range 1 thru 15); + penlabels (4', 5', 5'', 5''', 6', 6'', 6''', 7'); +fet_endchar; + + +def draw_heel = + save radius, thickness; + save pat; + path pat; + + radius# := .5 staff_space#; + + set_char_box (radius#, radius#, radius#, 2/3 staff_space#); + + thickness := hround (1.5 linethickness); + + pickup pencircle scaled thickness; + + rt x1 = b; + top y1 = h; + + x2 =x1; + y2 = 0; + + x3 = 0; + bot y3 = -d; + + pat := top z3{right} + .. lft z2{up} + -- lft z1 + .. top z1 + .. rt z1 + -- rt z2{down} + .. bot z3{left}; + pat := pat + -- reverse pat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + fill pat; +enddef; + + +fet_beginchar ("left heel", "upedalheel"); + draw_heel; + labels (1, 2, 3); +fet_endchar; + + +fet_beginchar ("right heel", "dpedalheel"); + draw_heel; + y_mirror_char; +fet_endchar; + + +def draw_toe = + save ht, wd, thickness; + + thickness := 1.5 linethickness; + ht# := 1.5 staff_space#; + wd# := 1/3 ht#; + define_pixels (ht, wd); + + set_char_box (wd#, wd#, 0, ht#); + draw_accent ((-h, -w), (0, w), thickness, 0.9); + currentpicture := currentpicture rotated -90; +enddef; + + +fet_beginchar ("left toe", "upedaltoe"); + draw_toe; +fet_endchar; + + +fet_beginchar ("right toe", "dpedaltoe"); + draw_toe; + y_mirror_char; +fet_endchar; + + +fet_beginchar ("Flageolet", "flageolet"); + save height, width, thickness, superness; + + height# = 4/15 staffsize#; + width# = height#; + thickness# = blot_diameter#; + define_pixels (height, width); + define_whole_blacker_pixels (thickness); + + set_char_box (width# / 2, width# / 2, height# / 2, height# / 2); + + penpos1 (thickness, 90); + penpos2 (thickness, 180); + penpos3 (thickness, 270); + penpos4 (thickness, 0); + + x1 = 0; + y1r = h; + x4r = w; + x2r = -x4r; + y2 = 0; + y4 = y2; + x3 = x1; + y3r = -y1r; + + penlabels (1, 2, 3, 4); + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if known miterlimit: + penstroke z1e + .. z2e + .. z3e + .. z4e + .. cycle; + else: + pickup pencircle scaled thickness; + draw z1 + .. z2 + .. z3 + .. z4 + .. cycle; + fi; +fet_endchar; + + +% +% TODO: ARGRGHGH code dup. +% + +fet_beginchar ("Segno", "segno"); + save thin, thick, ball_diam, darkness, pointheight; + save wd, ht, thick_nibangle, ball_nib_thick; + save turndir; + pair turndir; + + ht# = 3 staff_space#; + wd# = 2 staff_space#; + darkness = .08 staff_space + 0.4 linethickness; + + set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2); + + thick_nibangle = 30; + thick = 3 darkness; + thin = darkness; + ball_nib_thick = 2.7 darkness; + ball_diam = ball_nib_thick + (w - ball_nib_thick) / 10; + pointheight = 2 linethickness; + + y3l = h; + 2 x3 = x2 + x4; + x4 = 0; + y4 = y2; + y2l = .6 h; + x2l = -b; + z1 = (0, 0); + + penpos1 (thick, 2 thick_nibangle); + penpos2 (thick, thick_nibangle); + penpos3 (thin, -90); + penpos4 (ball_nib_thick, 180 - thick_nibangle); + + save swoosh, ploop; + path swoosh, ploop; + + swoosh := z1l{curl 0} + .. z2l + .. z3l{right} + .. {down}z4l + -- z4r + .. z3r{left} + .. z2r{down}; + fill swoosh + .. (swoosh scaled -1) + .. cycle; + + y5r = y4; + x5r = x4l - ball_diam / 2; + z6r = z5r; + + penpos5 (1.6 ball_diam / 2, 100); + penpos6 (ball_diam / 2, 240); + + ploop := z4l{down} + .. z5l + .. z6l + -- cycle; + fill ploop; + fill ploop scaled -1; + + penpos7 (2 thin, 0); + z7l = (-b, -d); + penpos8 (2 thin, 0); + z8r = (w, h); + + penstroke z7e + -- z8e; + + pickup pencircle scaled 2 thin; + drawdot (-x2r, pointheight); + drawdot (x2r, -pointheight); + + penlabels (range 1 thru 8); +fet_endchar; + + +fet_beginchar ("Coda", "coda"); + save stickout, thin, thick, codawidth, codaheight; + + stickout# = 0.35 staff_space#; + codawidth# = 2/3 staff_space#; + codaheight# = staff_space#; + define_pixels (codawidth, codaheight); + + set_char_box (codawidth# + stickout#, codawidth# + stickout#, + codaheight# + stickout#, codaheight# + stickout#); + + thin = 1.2 linethickness; + 0.1 (codaheight - 2 thin) = (codawidth - 2 thick); + + penpos1 (thick, 0); + penpos2 (thin, -90); + penpos3 (thick, -180); + penpos4 (thin, -270); + + x1l = -codawidth; + y2l = codaheight; + y1 = 0; + x2 = 0; + z3 = -z1; + z4 = -z2; + + penlabels (1, 2, 3, 4); + + fill z1l{up} + .. z2l{right} + .. z3l{down} + .. z4l{left} + .. cycle; + unfill z1r{up} + .. z2r{right} + .. z3r{down} + .. z4r{left} + .. cycle; + + draw_gridline ((0, -h), (0, h), thin); + draw_gridline ((-w, 0), (w, 0), thin); +fet_endchar; + + +fet_beginchar ("Varied Coda", "varcoda"); + save thin, thick, codawidth, codaheight; + thin# = 1.2 linethickness#; + thick# = 1.0 linethickness# + 0.25 staff_space#; + codawidth# = 2/3 staff_space#; + codaheight# = staff_space#; + define_pixels (thin, thick, codawidth, codaheight); + + set_char_box (codawidth# + thick#, codawidth# + thick#, + codaheight# + thick#, codaheight# + thick#); + + x1 = -codawidth + thick - .5 blot_diameter; + y1 = y2 - thin; + x2 = codawidth - thick + .5 blot_diameter; + y2 = codaheight; + draw_square_block (z1, z2); + + x3 = -codawidth; + y3 = -codaheight; + x4 = x3 + thick; + y4 = y2; + draw_block (z3, z4); + + labels (1, 2, 3, 4); + + addto currentpicture also currentpicture scaled -1; + + draw_gridline ((0, -h), (0, h), thin); + draw_gridline ((-w, 0), (w, 0), thin); +fet_endchar; + + +def draw_comma = + save alpha, thick, thin, ht; + + alpha := 35; + thin# = 1.2 linethickness#; + thick# = 3 linethickness#; + ht# = .6 staff_space#; + define_pixels (thin, thick, ht); + + set_char_box (0, .5 staff_space#, ht#, ht#); + + penpos1 (thick, alpha); + penpos2 (thick, alpha + 90); + penpos3 (thin, 180 - alpha); + penpos4 (thin, 90 - alpha); + + x3r = 0; + x1l = x3l; + y2r = -y4l = h; + z1 = z2; + z3 = z4; + + fill z1l{dir (alpha + 90)} + .. z2r{dir alpha} + .. z1r{dir (alpha - 90)} + .. z3l{dir (270 - alpha)} + .. z4l{dir (180 - alpha)} + .. z3r{dir (90-alpha)} + .. cycle; +enddef; + + +fet_beginchar ("Right Comma", "rcomma"); + draw_comma; + penlabels (1, 2, 3, 4); +fet_endchar; + + +fet_beginchar ("Left Comma", "lcomma"); + draw_comma; + xy_mirror_char; +fet_endchar; + + +def draw_varcomma = + save thick, thin, ht, wd, alpha; + + alpha := 35; + thin# = 1.2 linethickness#; + thick# = 3 linethickness#; + ht# = .6 staff_space#; + wd# = .25 staff_space#; + define_pixels (thin, thick, ht, alpha); + + set_char_box (wd#, wd#, ht#, ht#); + + z1 = (-b, -d); + z2 = (w, h); + + draw_brush (z1, thin, z2, thick); +enddef; + + +fet_beginchar ("Right Varied Comma", "rvarcomma"); + draw_varcomma; + labels (1, 2); +fet_endchar; + + +fet_beginchar ("Left Varied Comma", "lvarcomma"); + draw_varcomma; + xy_mirror_char; +fet_endchar; + + +thick# := 1/24 designsize; +define_blacker_pixels (thick); + +rthin := 0.075 * staff_space + 0.5 linethickness; +rthick := 2 thick + rthin; + + +def draw_arpeggio = + save alpha; + save ne, nw, se, sw; + save x, y; + pair ne, nw, se, sw; + + alpha := -40; + + nw = dir (alpha + 180); + ne = dir (alpha + 90); + se = dir alpha; + sw = dir (alpha - 90); + + penpos1 (rthin, alpha + 90); + penpos2 (5/4 rthick, alpha); + penpos3 (3/4 rthick, alpha); + penpos4 (5/4 rthick, alpha); + penpos5 (rthin, alpha + 90); + + z1 = (width / 2, height) - overshoot * se; + z2 = 2 [z4, (width / 2, height / 2)]; + z3 = 1/2 [z2, z4]; + x4 = 2/8 staff_space; + y4 = rthin; + + z5 = 2 [z1, (width / 2, height / 2)]; + z6 = z2l + 1/2 rthin * sw; + z7 = z4l + 1/2 rthin * sw + 1/2 rthin * se; + z8 = 2 [z6, (width / 2, height / 2)]; + z9 = 2 [z7, (width / 2, height / 2)]; + + fill z1l{se} + -- z6 + .. z3l + .. z7{se} + -- z5l + .. z5r{nw} + -- z8 + .. z3r + .. z9{nw} + -- z1r + .. cycle; +enddef; + + +fet_beginchar ("Arpeggio", "arpeggio"); + save height, overshoot, width; + height# = staff_space#; + width# = 0.8 height#; + overshoot# = 0.25 staff_space#; + define_pixels (height, overshoot, width); + + set_char_box (0, width#, 0, height#); + draw_arpeggio; + penlabels (range 1 thru 9); + + draw_staff (-2, 2, 0.0); +fet_endchar; + + +% +% Extendable Trill symbol. +% Not yet used +% Rename me to Trill, rename Trill to Tr? +% + +fet_beginchar ("Trill_element", "trill_element"); + save height, overshoot; + height# = staff_space#; + width# = 0.8 height#; + overshoot# = 0.25 staff_space#; + define_pixels (height, overshoot, width); + + set_char_box (0, height#, 0, width#); + draw_arpeggio; + + currentpicture := currentpicture shifted -(width / 2, height / 2); + currentpicture := currentpicture rotated 90; + currentpicture := currentpicture shifted (height / 2, width / 2); +fet_endchar; + + +% +% Arpeggio arrow by Chris Jackson <chris@fluffhouse.org.uk> +% + +def draw_arpeggio_arrow = + save thinness, height, width, overshoot; + save nw, ne, se, sw; + save alpha; + save before_left, before_right, after_left, after_right; + save u_left, v_left, u_right, v_right; + pair nw, ne, se, sw; + path before_left, before_right, after_left, after_right; + + height# = staff_space#; + width# = 0.8 height#; + overshoot# = 0.25 staff_space#; + define_pixels (height, overshoot, width); + + set_char_box (0, width#, 0, height#); + + alpha := -40; + nw = dir (alpha + 180); + ne = dir (alpha + 90); + se = dir alpha; + sw = dir (alpha - 90); + + penpos1 (rthin, alpha + 90); + penpos2 (5/4 rthick, alpha); + penpos3 (5/4 rthick, 0); + + z1 = (width / 2, height) - overshoot * se; % numbering is consistent + % with the arpeggio symbol + z2 = 2 [z4, (width / 2, height / 2)]; + z3 = (0.5 width, 0.5 height); + z4 = (0.25 staff_space, rthin); + z6 = z2l + 1/2 rthin * sw; + z9 = (width / 2, height) + overshoot * se; + + pickup pencircle scaled vround (0.5 rthin); + + bot z10 = (0.5 w, 0); + lft z11 = (0.5 w - hround (0.8 w), 0.8 h); + rt z12 = (0.5 w + hround (0.8 w), 0.8 h); + + before_left := z1l + -- z6{z6 - z1l} + .. {down}z3l; + after_left := (z3 + (0, -0.25 rthin / cosd (angle (nw)))) + -- (z11 + 0.25 rthin * ne); + (u_left, v_left) = before_left intersectiontimes after_left; + + before_right := (z12 + 0.25 rthin * nw) + -- (z3 + (0, -0.25 rthin / cosd (angle (nw)))); + after_right := z3r{up} + .. z9{z1r - z9} + -- z1r; + (u_right, v_right) = before_right intersectiontimes after_right; + + fill subpath (0, u_left) of before_left + .. subpath (v_left, infinity) of after_left + .. top z11 + .. lft z11 + .. {dir -50}(z11 + 0.25 rthin * sw) + .. (z10 + 0.25 rthin * sw){dir -70} + .. bot z10 + .. {dir 70}(z10 + 0.25 rthin * se) + .. (z12 + 0.25 rthin * se){dir 50} + .. rt z12 + .. top z12 + .. subpath (0, u_right) of before_right + .. subpath (v_right, infinity) of after_right + .. cycle; + + % mf doesn't handle pixel dropouts in outline objects, so we use + % `draw' if not called by mpost + if not known miterlimit: + pickup pencircle scaled 0.7 rthin; + draw z1 + -- (z9 + 0.5 rthin * dir (alpha - 90)); + fi; +enddef; + + +fet_beginchar ("Arpeggio arrow down", "arpeggio.arrow.M1"); + draw_arpeggio_arrow; + penlabels (range 1 thru 12); +fet_endchar; + + +fet_beginchar ("Arpeggio arrow up", "arpeggio.arrow.1"); + draw_arpeggio_arrow; + currentpicture := currentpicture scaled -1 + shifted (w - feta_eps, h - feta_eps); +fet_endchar; + + +% Hmm +input feta-slag; + + +% +% Railroad tracks. We define two variants of these -- both as slightly +% tapered, comma-shaped curves and as two straight parallel slashes. +% + +fet_beginchar ("Curved caesura", "caesura.curved"); + save slant, space_between, clearance; + save alpha, pat; + save botthick, topthick; + save krom; + path pat; + + botthick = 1.5 linethickness; + topthick = 2.5 linethickness; + + pickup pencircle scaled botthick; + + slant = 3.5; + space_between# = 0.6 staff_space#; + clearance# = 0.2 staff_space#; + height# = 1.2 staff_space#; + + set_char_box (0, 2.0 staff_space#, + staff_space# - clearance#, height#); + define_pixels (clearance, height); + define_whole_pixels (space_between); + + bot y1 = -d; + top y2 = h; + + lft x1 = 0; + x2 = (y2 - y1) / slant; + + krom = 10; + + alpha = angle (z2 - z1); + penpos1 (botthick, alpha - krom); + penpos3 (botthick, alpha - krom + 90); + + penpos2 (topthick, alpha + krom); + penpos4 (topthick, alpha + krom + 90); + + z3 = z1; + z4 = z2; + + penlabels (1, 2, 3, 4); + + pat := z3r{(z1r - z1l)} + .. z4r{z2r-z2l} + .. z2r{z4l-z4r} + .. z4l{z2l-z2r} + .. z3l{z1l-z1r} + .. z1l{z3r-z3l} + .. cycle; + fill pat; + fill pat shifted (space_between, 0); +fet_endchar; + + +fet_beginchar ("Straight caesura", "caesura.straight"); + save slant, space_between, clearance; + save thick, ne, pat; + path pat; + pair ne; + + slant = 2.0; + thick = 2.88 linethickness; + + space_between# = 0.56 staff_space#; + clearance# = 0.2 staff_space#; + + set_char_box (0, 2.0 staff_space#, + staff_space# - clearance#, 1.2 staff_space#); + define_whole_pixels (space_between); + + x1 = 0; + x2 = x1 + thick; + y1 = y2 = -d; + + x3 = x4 + thick; + x4 = x1 + (h + d) / slant; + y3 = y4 = h; + + ne = unitvector (z4 - z1); + + z1a = z1 + blot_diameter * ne; + z1b = z1 + blot_diameter * right; + z2a = z2 + blot_diameter * ne; + z2b = z2 + blot_diameter * left; + + z3a = z3 - blot_diameter * ne; + z3b = z3 + blot_diameter * left; + z4a = z4 - blot_diameter * ne; + z4b = z4 + blot_diameter * right; + + pat = z1a{-ne} + .. {right}z1b + -- z2b{right} + .. {ne}z2a + -- z3a{ne} + .. {left}z3b + -- z4b{left} + .. {-ne}z4a + -- cycle; + + fill pat; + fill pat shifted (space_between, 0); + + labels(range 1 thru 4); + labels(1a, 1b, 2a, 2b, 3a, 3b, 4a, 4b); +fet_endchar; + +fet_endgroup ("scripts"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-slag.mf b/muse2/share/scoreglyphs/feta-original/feta-slag.mf new file mode 100644 index 00000000..3b054103 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-slag.mf @@ -0,0 +1,315 @@ +% -*- Fundamental -*- (emacs-20 mf mode sucks) +% feta-slag.mf -- implement trill symbols +% +% source file of the Feta (definitely not an abbreviation for Font-En-Tja) +% music font +% +% (c) 1998--2009 Jan Nieuwenhuizen <janneke@gnu.org> +% + +% this file is included by feta-scripts.mf + +trill_thin# = 0.1 staff_space# + 0.6 stafflinethickness#; +trill_stemwidth# = trill_thin#; +define_pixels (trill_thin); +define_whole_blacker_pixels (trill_stemwidth); + +trill_thick = 1/2 staff_space; +trill_overlap = 1/6 staff_space; + +trill_width# = 5/6 staff_space#; +trill_height# = 1/2 staff_space#; +define_pixels (trill_height); +define_whole_pixels (trill_width); + +pair trill_ne; +trill_ne := unitvector ((2, 3)); + + +% +% The trill element sticks out on both the left and right side +% of the normal bbox, so you can glue them together easily. +% +% `ending' is either 0 for none, 1 for left, or 2 for right. +% + +def draw_trillelement (expr offset, ending) = + clearxy; + +begingroup; + save nw, pat, nw_dist, ne_dist; + pair nw, nw_dist, ne_dist; + path pat; + + pickup pencircle scaled trill_thin; + + x1 = -.5 trill_width; + y1 = 0; + z3 = whatever * trill_ne + z1; + top y3 = vround trill_height; + z2 = z3 - (trill_thick - trill_thin) * trill_ne; + + bot z3' = (top z3) scaled -1; + + nw = unitvector (z2 - z3'); + ne_dist = (nw rotated -90) * 0.5 trill_thin; + nw_dist = (trill_ne rotated 90) * 0.5 trill_thin; + + z5 = whatever * trill_ne + (z1 - nw_dist); + z5 = whatever * nw + (z3' - ne_dist); + + pat := z5 + -- (z1 - nw_dist){-trill_ne} + -- (z1 + nw_dist){trill_ne} + -- (z3 + nw_dist){trill_ne} + .. top z3{right} + .. (z3 + ne_dist){-nw}; + pat := pat + -- pat scaled -1 shifted (-feta_eps, -feta_eps) + -- cycle; + pat := pat shifted (offset, 0); + fill pat; + + z4 = z1 - trill_ne * trill_overlap; + x4 := hround (x4 + 0.5 trill_thin) - 0.5 trill_thin; + + pat := (z4 - nw_dist){-trill_ne} + .. bot z4{left} + .. lft z4{up} + .. (z4 + nw_dist){trill_ne} + -- (z1 + nw_dist){trill_ne} + -- (z1 - nw_dist){-trill_ne} + -- cycle; + + if ending = 1: + fill pat shifted (offset, 0); + elseif ending = 2: + pat := pat scaled -1 shifted (-feta_eps, -feta_eps); + fill pat shifted (offset, 0); + fi; +endgroup; +enddef; + + +fet_beginchar ("trilelement", "trilelement"); + set_char_box (.5 trill_width#, .5 trill_width#, + trill_height#, trill_height#); + + draw_trillelement (0, 0); + labels (1, 2, 3, 3', 4, 5, 5'); +fet_endchar; + + +fet_beginchar ("prall", "prall"); + set_char_box (trill_width#, trill_width#, + trill_height#, trill_height#); + + draw_trillelement (-hround (.5 trill_width), 1); + draw_trillelement (-hround (.5 trill_width) + trill_width, 2); +fet_endchar; + + +fet_beginchar ("mordent", "mordent"); + set_char_box (trill_width#, trill_width#, + 4/3 trill_height#, 4/3 trill_height#); + + draw_trillelement (-hround (.5 trill_width), 1); + draw_trillelement (-hround (.5 trill_width) + trill_width, 2); + + clearxy; + + pickup pencircle scaled trill_stemwidth; + + top y1 = h; + bot y2 = -d; + x1 = x2; + x2 = 0; + + draw_gridline (z2, z1, trill_stemwidth); + + labels (1, 2); +fet_endchar; + + +fet_beginchar ("prallprall", "prallprall"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, trill_height#); + + draw_trillelement (-trill_width, 1); + draw_trillelement (0, 0); + draw_trillelement (trill_width, 2); +fet_endchar; + + +fet_beginchar ("prallmordent", "prallmordent"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + 4/3 trill_height#, 4/3 trill_height#); + + draw_trillelement (-trill_width, 1); + draw_trillelement (0, 0); + draw_trillelement (trill_width, 2); + + clearxy; + + pickup pencircle scaled trill_stemwidth; + + top y1 = h; + bot y2 = -d; + x1 = x2 ; + x2 = good.x (.5 trill_width); + + draw_gridline (z2, z1, trill_stemwidth); + + labels (1, 2); +fet_endchar; + + +save remember_pic; +picture remember_pic; + + +fet_beginchar ("upprall", "upprall"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, trill_height#); + + draw_trillelement (-trill_width, 1); + draw_trillelement (0, 0); + draw_trillelement (trill_width, 2); + + z11 = z4 shifted (-trill_width, 0); + z12 = z11 + (0, -2 trill_height); + + penpos11 (trill_thin, angle (trill_ne) - 90); + penpos12 (trill_thin, angle (trill_ne yscaled -1) + 90); + penlabels (11, 12); + + pickup pencircle scaled trill_stemwidth; + + fill z11l{-trill_ne} + .. z12l{trill_ne yscaled -1} + .. bot z12 + .. rt z12 + .. z12r{-trill_ne yscaled -1} + .. z11r{trill_ne} + -- cycle; + + remember_pic := currentpicture; +fet_endchar; + + +fet_beginchar ("upmordent", "upmordent"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + 4/3 trill_height#, 4/3 trill_height#); + + currentpicture := remember_pic; + + clearxy; + + pickup pencircle scaled trill_stemwidth; + + top y1 = h; + bot y2 = -d; + x1 = x2; + x2 = good.x (.5 trill_width); + + draw_gridline (z2, z1, trill_stemwidth); + + labels (1, 2); +fet_endchar; + + +fet_beginchar ("pralldown", "pralldown"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, trill_height#); + + currentpicture := remember_pic xscaled -1; +fet_endchar; + + +fet_beginchar ("downprall", "downprall"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, trill_height#); + + draw_trillelement (-trill_width, 1); + draw_trillelement (0, 0); + draw_trillelement (trill_width, 2); + + z11 = z4 shifted (-trill_width, 0); + z12 = z11 + (0, 2 trill_height); + + penpos11 (trill_thin, angle (trill_ne xscaled -1) - 90); + penpos12 (trill_thin, angle (trill_ne) - 90); + penlabels (11, 12); + + pickup pencircle scaled trill_stemwidth; + + fill z11l{trill_ne xscaled -1} + .. z12l{trill_ne} + .. top z12 + .. rt z12 + .. z12r{-trill_ne} + .. z11r{-trill_ne xscaled -1} + -- cycle; + + remember_pic := currentpicture; +fet_endchar; + + +fet_beginchar ("downmordent", "downmordent"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + 4/3 trill_height#, 4/3 trill_height#); + + currentpicture := remember_pic; + + clearxy; + + pickup pencircle scaled trill_stemwidth; + + top y1 = h; + bot y2 = -d; + x1 = x2; + x2 = good.x (.5 trill_width); + + draw_gridline (z2, z1, trill_stemwidth); + + labels (1, 2); +fet_endchar; + + +fet_beginchar ("prallup", "prallup"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, trill_height#); + + currentpicture := remember_pic xscaled -1; +fet_endchar; + + +fet_beginchar ("lineprall", "lineprall"); + set_char_box (1.5 trill_width#, 1.5 trill_width#, + trill_height#, 4 trill_height#); + + draw_trillelement (-trill_width, 1); + + labels (1, 2, 3, 3', 4, 5, 5'); + + pickup pencircle scaled trill_stemwidth; + + penpos10 (trill_stemwidth, 0); + penpos11 (trill_stemwidth, 0); + + x10l = x4 - .5 trill_thin - trill_width; + y10 = y4; + z11 = z10 + (0, h); + + penlabels (10, 11); + + fill z11l + .. top z11 + .. z11r + -- z10r + -- z10l + -- cycle; + + draw_trillelement (0, 0); + draw_trillelement (trill_width, 2); +fet_endchar; diff --git a/muse2/share/scoreglyphs/feta-original/feta-test-generic.mf b/muse2/share/scoreglyphs/feta-original/feta-test-generic.mf new file mode 100644 index 00000000..1ade03f2 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test-generic.mf @@ -0,0 +1,20 @@ +% +% test stuff. +% in a separate file to avoid tainting non-test font files for testing. +% + +%input feta-eindelijk; +input feta-toevallig; +%input feta-puntje; +%input feta-bolletjes; +%input feta-arrow; +%input feta-schrift; +%input feta-schrift; +%input feta-banier; +% input feta-slag; +%input feta-klef; +%input feta-haak; +% input feta-haak; +%input feta-timesig; +%input feta-pendaal; +%input feta-accordion; diff --git a/muse2/share/scoreglyphs/feta-original/feta-test11.mf b/muse2/share/scoreglyphs/feta-original/feta-test11.mf new file mode 100644 index 00000000..ad21720a --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test11.mf @@ -0,0 +1,15 @@ +% feta-test11.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 11; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-test13.mf b/muse2/share/scoreglyphs/feta-original/feta-test13.mf new file mode 100644 index 00000000..28abf42c --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test13.mf @@ -0,0 +1,16 @@ +% feta-test13.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 13; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-test16.mf b/muse2/share/scoreglyphs/feta-original/feta-test16.mf new file mode 100644 index 00000000..eaa280aa --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test16.mf @@ -0,0 +1,16 @@ +% feta-test16.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 16; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-test20.mf b/muse2/share/scoreglyphs/feta-original/feta-test20.mf new file mode 100644 index 00000000..5a58be3d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test20.mf @@ -0,0 +1,16 @@ +% feta-test20.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 20; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-test23.mf b/muse2/share/scoreglyphs/feta-original/feta-test23.mf new file mode 100644 index 00000000..5a25b469 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test23.mf @@ -0,0 +1,16 @@ +% feta-test23.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 23; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta-test26.mf b/muse2/share/scoreglyphs/feta-original/feta-test26.mf new file mode 100644 index 00000000..e9e15218 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-test26.mf @@ -0,0 +1,15 @@ +% feta-test26.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 26; +test := 1; + +% smoked cheese +% test := -1; + +input feta-generic; + + +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta-timesig.mf b/muse2/share/scoreglyphs/feta-original/feta-timesig.mf new file mode 100644 index 00000000..ffaa1883 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-timesig.mf @@ -0,0 +1,108 @@ +% +% feta-timesig.mf -- implement Time Signatures +% +% source file of the Feta (not an abbreviation of Font-En-Tja) music font +% +% (c) 1998--2009 Mats Bengtsson <matsb@s3.kth.se>, +% Christian Mondrup <scancm@biobase.dk> + +fet_begingroup ("timesig"); + + +% +% Originally by Mats B. nuked by Han-Wen, inspired by +% Baerenreiter BA320 (Bach Cello Suites, Suite III). +% +% Notes: +% +% * The inside curve of the C is rather straight. +% * The outside curve of the C is rather round. +% * Right tips of the C point slightly outward. +% * Lower tip protrudes to the right very slightly. +% + +def draw_C = + save hair, bulb_rad, left_fatness; + save left_width, right_width; + save width, lower_offset; + + width# := 1.8 staff_space# - stafflinethickness#; + + left_width := 1.0 staff_space; + right_width := 0.8 staff_space; + + hair := stafflinethickness; + + bulb_rad := 0.40 staff_space - .6 stafflinethickness; + left_fatness := 0.55 * staff_space; + lower_offset := 0.3 stafflinethickness; + + set_char_box (0, width#, staff_space#, staff_space#); + + d := d - feta_shift; + + x1r = w; + x3r = 0; + y1r = .45 h; + y2r = h + vround (.5 stafflinethickness_rounded); + y4r = -d - vround (.5 stafflinethickness_rounded); + x2 = x4; + x2 = x3r + h; + y3r = .5 (h - d); + + x5r = x1r + lower_offset; + y5r = -0.37 h; + + penpos1 (hair, 10); + penpos2 (stafflinethickness_rounded, 90); + penpos3 (left_fatness, 180); + penpos4 (stafflinethickness_rounded, -90); + penpos5 (hair, -13); + + draw_bulb (-1, z1l, z1r, bulb_rad, .8); + + save s; + s := 0.735; + + fill z1l{dir (100)} + .. z2l{left} + ..tension 0.8.. z3l{down} + ..tension 0.8.. z4l{right} + .. simple_serif (z5l, z5r, -90) + .. z4r{left} + .. super_curvelet (z4r, z3r, s, -1) + .. z3r{up} + .. super_curvelet (z3r, z2r, s, 1) + .. z2r{right} + .. {dir (-80)}z1r + -- cycle; + + penlabels (1, 2, 3, 4, 5); + + draw_staff (-2, 2, 0); +enddef; + + +fet_beginchar ("4/4 meter", "C44"); + draw_C; +fet_endchar; + + +fet_beginchar ("2/2 meter", "C22"); + save eccentricity, top_stemlen, bottom_stemlen, thick, left_pos; + + draw_C; + + eccentricity = -1.75 stafflinethickness - 0.025 staff_space; + top_stemlen# = bottom_stemlen# = 1.4 staff_space#; + thick# = stafflinethickness# + 0.05 staff_space#; + define_whole_pixels (top_stemlen, bottom_stemlen); + define_whole_blacker_pixels (thick); + + bottom_stemlen := bottom_stemlen - feta_shift; + + draw_block ((x2 + eccentricity, -bottom_stemlen), + (x2 + eccentricity + thick, top_stemlen)); +fet_endchar; + +fet_endgroup ("timesig"); diff --git a/muse2/share/scoreglyphs/feta-original/feta-toevallig.mf b/muse2/share/scoreglyphs/feta-original/feta-toevallig.mf new file mode 100644 index 00000000..48061fcd --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta-toevallig.mf @@ -0,0 +1,1308 @@ +% +% feta-toevallig.mf -- implement Accidentals +% +% (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl> +% + + +% +% also show in other configuration wrt staff lines. +% +def draw_shifted_too = +if test > 0: + fet_beginchar ("shifted too", ""); + set_char_box (0, 0, 0, 0); + currentpicture := remember_pic; + + draw_staff (-2, 2, 0.5); + fet_endchar; +fi; +enddef; + + +% +% Accidentals from various sources, notably +% +% Baerenreiter edition of Schuberts `Auf dem Strom' (sharp, natural) +% F Hofmeister edition of Muellers `Etueden fuer Horn' (double sharp, flat) +% + + +% +% Naming for accidentals (including microtonal variants): +% +% SHARPBASE[.SLASHES.STEMS] +% FLATBASE[.MODIFIER] +% +% Examples: +% +% sharp.slashslash.stem +% mirroredflat.flat +% +% + + +fet_begingroup ("accidentals"); + +% +% Draw an arrow +% +% * `stemslant' gives the direction of the stem's left boundary +% (needed for brushed stems, equals "up" for straight stems) +% * `extend' is used to make the stem longer or shorter (if negative); +% different kinds of accidentals need different values here +% +def draw_arrow (expr attach, stemwidth, stemslant, extend, pointingdown) = +begingroup; + save htip; % tip height + save wwing; % wing `radius' + save angle_wing_bot, angle_wing_top, angle_tip; + save upshift; + clearxy; + + wwing := 0.26 stemwidth; + htip := staff_space * 0.85 + stafflinethickness - wwing; + + % `flip' is used to reflect the arrow vertically + % if arrow points downward + transform flip; + if pointingdown: + flip = identity reflectedabout (origin, right); + else: + flip = identity; + fi; + + z1 = attach shifted (-stemwidth / 2, 0); + upshift := max (0, wwing + 0.1 staff_space + extend); + z2 = z1 shifted (((unitvector stemslant) + scaled upshift) transformed flip); + + z7 = attach shifted ((stemwidth/2),0); + z6 = z7 shifted (((unitvector (-xpart stemslant, ypart stemslant)) + scaled upshift) transformed flip); + z2 - z3 = ( 0.38 staff_space, 0.05 htip) transformed flip; + z6 - z5 = (-0.38 staff_space, 0.05 htip) transformed flip; + + z4 = attach shifted ((-0.2 stemwidth, upshift + htip) + transformed flip); + z4'= attach shifted (( 0.2 stemwidth, upshift + htip) + transformed flip); + + % `angle_wing_bot' is the angle at which the arc + % from z2 to z3a enters z3a + % `angle_wing_top' is the angle at which the arc + % from z3b to z4 leaves z3b + % `angle_tip' is the angle at which the arc + % from z4 to z4' leaves z4 + angle_wing_bot = 30; + angle_wing_top = 55; + angle_tip = 68; + + z3a = z3 shifted ((((dir angle_wing_bot) rotated -90) + scaled wwing) transformed flip); + z3b = z3 shifted ((((dir angle_wing_top) rotated 90) + scaled wwing) transformed flip); + + z5a = z5 shifted ((((dir (180 - angle_wing_bot)) rotated 90) + scaled wwing) transformed flip); + z5b = z5 shifted ((((dir (180 - angle_wing_top)) rotated -90) + scaled wwing) transformed flip); + + % Draw the arrow + pickup pencircle scaled 1; + fill z1 + -- z2{stemslant transformed flip} + .. {(-dir angle_wing_bot) transformed flip}z3a + .. z3b{(dir angle_wing_top) transformed flip} + .. z4{(dir angle_tip) transformed flip} + .. z4'{(dir (-angle_tip)) transformed flip} + .. {(dir (-angle_wing_top)) transformed flip}z5b + .. z5a{(-dir (-angle_wing_bot)) transformed flip} + .. z6{((-stemslant) reflectedabout (origin, up)) transformed flip} + -- z7 + -- cycle; + + labels (range 0 thru 7, 4', 3a, 3b, 5a, 5b); +endgroup; +enddef; + +save remember_pic; +picture remember_pic; + +save sharp_beamheight; +sharp_beamheight# := 0.3 staff_space# + stafflinethickness#; + +% +% The beams of most sharps have horizontal endings (as if drawn with +% a square pen). [Wanske] does not mention this, so we'll just ignore +% this fact. +% + +def draw_meta_sharp (expr width, offset) = + save beamwidth, beamslope; + save ne, nw_dist; + pair ne, nw_dist; + + beamwidth := width; + + define_whole_vertical_blacker_pixels (sharp_beamheight); + + clearxy; + + beamslope = sharp_beamheight / beamwidth; + + pickup pencircle scaled 2 blot_diameter; + + rt x2 - lft x1 = beamwidth; + z2 = z1 + whatever * (beamwidth, sharp_beamheight); + .5 [z1, z3] = (.5 w, offset); + x3 = x2; + top y2 - bot y3 = sharp_beamheight; + x4 = x1; + top y1 - bot y4 = sharp_beamheight; + + ne = unitvector (z2 - z1); + nw_dist = (ne rotated 90) * blot_diameter; + + fill lft z1{up} + ... (z1 + nw_dist){ne} + -- (z2 + nw_dist){ne} + ... rt z2{down} + -- rt z3{down} + ... (z3 - nw_dist){-ne} + -- (z4 - nw_dist){-ne} + ... lft z4{up} + -- cycle; + + labels (1, 2, 3, 4); +enddef; + + +def draw_sharp(expr arrowup, arrowdown) = + save stem, stemx, stemwidth; + save outer_space, interbeam; + save stemlength, extendleft, extendright, height, depth; + + stemwidth# := stafflinethickness# + .05 staff_space#; + define_whole_blacker_pixels (stemwidth); + + interbeam := 1.05 staff_space_rounded; + + stemlength# := 1.5 staff_space#; + define_pixels (stemlength); + + height# = stemlength#; + depth# = stemlength#; + extendright# = 0; + extendleft# = 0; + if arrowup: + height# := height# + 1.2 staff_space#; + extendright# := extendright# + 1.5 stafflinethickness#; + fi; + if arrowdown: + depth# := depth# + 1.2 staff_space#; + extendleft# := extendleft# + 1.5 stafflinethickness#; + fi; + define_pixels (extendleft, extendright); + set_char_box (extendleft#, 1.1 staff_space#, depth#, height#); + + stem := 7 / 16 * w; + stemx := hround stem; + outer_space := hround ((w - stemx - stemwidth) / 2); + + w := 2 outer_space + stemx + stemwidth; + d := d - feta_space_shift; + + draw_meta_sharp (w, -.5 interbeam); + draw_meta_sharp (w, -.5 interbeam + vround interbeam); + + % expand the charbox so that it encloses the whole arrow; + % this must not happen earlier because some commands above + % still rely on the old width + w := w + extendright; + + pickup pencircle scaled stemwidth; + + lft x5 = lft x6 = outer_space; + lft x7 = lft x8 = outer_space + stemx; + bot y5 = -stemlength; + top y6 = vround (1.5 staff_space - stem * beamslope); + bot y7 = -top y6 + feta_space_shift; + top y8 = stemlength; + + labels (5, 6, 7, 8); + + draw_gridline (z5, z6, stemwidth); + draw_gridline (z7, z8, stemwidth); + + if arrowup: + draw_arrow (z8, stemwidth, up, + stafflinethickness / 2 + stemwidth / 2, false); + fi; + if arrowdown: + draw_arrow (z5, stemwidth, up, + stafflinethickness / 2 + stemwidth / 2, true); + fi; + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +enddef; + + +fet_beginchar ("Sharp", "sharp"); + draw_sharp (false, false); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Sharp (arrow up)", "sharp.arrowup"); + draw_sharp (true, false); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Sharp (arrow down)", "sharp.arrowdown"); + draw_sharp (false, true); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Sharp (arrows up and down)", "sharp.arrowboth"); + draw_sharp (true, true); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("1/2 Sharp", "sharp.slashslash.stem"); + save stem, stemwidth; + save outer_space, interbeam; + + stemwidth# := stafflinethickness# + .05 staff_space#; + define_whole_blacker_pixels (stemwidth); + + interbeam := 1.05 staff_space_rounded; + + set_char_box (0, 0.7 staff_space#, + 1.5 staff_space#, 1.5 staff_space#); + + stem := 7 / 16 * w; + outer_space := hround ((w - stemwidth) / 2); + + w := 2 outer_space + stemwidth; + d := d - feta_space_shift; + + draw_meta_sharp (w, -.5 interbeam); + draw_meta_sharp (w, -.5 interbeam + vround interbeam); + + pickup pencircle scaled stemwidth; + + lft x5 = lft x6 = outer_space; + top y6 = vround (1.5 staff_space - .5 stem); + bot y5 = -top y6 + feta_space_shift; + + labels (5, 6); + + draw_gridline (z5, z6, stemwidth); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Sharp (3 beams)", "sharp.slashslashslash.stemstem"); + save stem, stemx, stemwidth; + save outer_space, interbeam; + save sharp_beamheight; + + sharp_beamheight# := 0.22 staff_space# + stafflinethickness#; + + stemwidth# := stafflinethickness# + .05 staff_space#; + define_whole_blacker_pixels (stemwidth); + + interbeam := 1.2 staff_space_rounded; + + set_char_box (0, 1.1 staff_space#, + 1.5 staff_space#, 1.5 staff_space#); + + stem := 7 / 16 * w; + stemx := hround stem; + outer_space := hround ((w - stemx - stemwidth) / 2); + + w := 2 outer_space + stemx + stemwidth; + d := d - feta_space_shift; + + draw_meta_sharp (.88 w, -.5 interbeam); + draw_meta_sharp (.88 w, -.5 interbeam + vround interbeam); + sharp_beamheight# := 1/.88 sharp_beamheight#; + draw_meta_sharp (w, 0); + + pickup pencircle scaled stemwidth; + + lft x5 = lft x6 = outer_space; + lft x7 = lft x8 = outer_space + stemx; + bot y5 = -d; + top y6 = vround (1.5 staff_space - stem * beamslope); + bot y7 = -top y6 + feta_space_shift; + top y8 = h; + + labels (5, 6, 7, 8); + + draw_gridline (z5, z6, stemwidth); + draw_gridline (z7, z8, stemwidth); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("1/2 Sharp (3 beams)", "sharp.slashslashslash.stem"); + save stem, stemx, stemwidth; + save outer_space, interbeam; + save sharp_beamheight; + + sharp_beamheight# := 0.22 staff_space# + stafflinethickness#; + + stemwidth# := stafflinethickness# + .05 staff_space#; + define_whole_blacker_pixels (stemwidth); + + interbeam := 1.2 staff_space_rounded; + + set_char_box (0, 0.95 staff_space#, + 1.3 staff_space#, 1.3 staff_space#); + + stem := 7 / 16 * w; + outer_space := hround ((w - stemwidth) / 2); + + w := 2 outer_space + stemwidth; + d := d - feta_space_shift; + + draw_meta_sharp (.8 w, -.5 interbeam); + draw_meta_sharp (.8 w, -.5 interbeam + vround interbeam); + sharp_beamheight# := 1/.8 sharp_beamheight#; + draw_meta_sharp (w, 0); + + pickup pencircle scaled stemwidth; + + lft x5 = lft x6 = outer_space; + top y6 = vround (1.5 staff_space - .5 stem); + bot y5 = -top y6 + feta_space_shift; + labels (5, 6); + + draw_gridline (z5, z6, stemwidth); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("3/4 Sharp", "sharp.slashslash.stemstemstem"); + save stem, stemx, stemwidth; + save outer_space, interbeam; + + stemwidth# := stafflinethickness# + .05 staff_space#; + define_whole_blacker_pixels (stemwidth); + + interbeam := 1.05 staff_space_rounded; + + set_char_box (0, 1.6 staff_space#, + 1.5 staff_space#, 1.5 staff_space#); + + stem := 9 / 32 * w; + stemx := hround stem; + outer_space := hround ((w - 2 stemx - stemwidth) / 2); + + w := 2 outer_space + 2 stemx + stemwidth; + d := d - feta_space_shift; + + draw_meta_sharp (w, -.5 interbeam); + draw_meta_sharp (w, -.5 interbeam + vround interbeam); + + pickup pencircle scaled stemwidth; + + lft x5 = lft x6 = outer_space; + lft x7 = lft x8 = outer_space + stemx; + lft x9 = lft x10 = outer_space + 2 stemx; + bot y5 = -d; + top y6 = vround (1.5 staff_space - 2 stem * beamslope); + bot y9 = -top y6 + feta_space_shift; + top y10 = h; + y7 = .5 [y5, y9]; + y8 = .5 [y6, y10]; + + labels (5, 6, 7, 8, 9, 10); + + draw_gridline (z5, z6, stemwidth); + draw_gridline (z7, z8, stemwidth); + draw_gridline (z9, z10, stemwidth); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +% +% The stems of the natural are brushed (at least, in Barenreiter SCS) +% + +def draw_natural (expr arrowup, arrowdown) = + save stemwidth, top_stem_thick; + save ne, pat_top, pat_bottom; + save depth, height, extendleft, extendright, stemlength; + save brush_scale_up, brush_scale_down; + pair ne; + path pat_top, pat_bottom; + + top_stem_thick# = stafflinethickness# + .10 staff_space#; + stemwidth# = 0.09 staff_space# + .5 stafflinethickness#; + define_whole_blacker_pixels (top_stem_thick, stemwidth); + + stemlength# = 1.5 staff_space#; + define_pixels (stemlength); + + height# = stemlength#; + depth# = stemlength#; + extendleft# = 0; + extendright# = 0; + if arrowup: + extendleft# := 3 stafflinethickness#; + height# := height# + 1.2 staff_space#; + fi; + if arrowdown: + extendright# := 3.15 stafflinethickness#; + depth# := depth# + 1.2 staff_space#; + fi; + define_pixels (extendright); + + set_char_box (extendleft#, 2/3 staff_space#, depth#, height#); + + d := d - feta_space_shift; + + pickup pencircle scaled stemwidth; + + brush_scale_up := 1.0; + brush_scale_down := 1.0; + % to look nice, arrowed stems must be less brushed + if arrowup: + brush_scale_up := 0.85; + fi; + if arrowdown: + brush_scale_down := 0.85; + fi; + + penpos1 (top_stem_thick, 0); + penpos3 (top_stem_thick, 0); + penpos2 (stemwidth, 0); + penpos4 (stemwidth, 0); + % z1' and z3' are needed for the arrowed accidentals + penpos1' (top_stem_thick * brush_scale_up, 0); + penpos3' (top_stem_thick * brush_scale_down, 0); + + x2r = w; + x4l = 0; + x3 = x3' = x2; + x1 = x1' = x4; + + y1 = y1' = stemlength; + y3 = y3' = -stemlength; + top y2 = vround (staff_space - 3/2 stafflinethickness); + y4 = -y2 + feta_space_shift; + + pat_bottom := z4r{z4r - z1r} + .. bot z4 + .. z4l{z1l - z4l}; + fill simple_serif (z1'l, z1'r, -30) + -- pat_bottom + -- cycle; + + pat_top := z2r{z2r - z3r} + .. top z2 + .. z2l{z3l - z2l}; + fill simple_serif (z3'l, z3'r, 30) + -- pat_top + -- cycle; + + ne = (x2 - x4, stafflinethickness); + + z11' = z3l + whatever * (z2l - z3l); + y11' = vround (.5 (staff_space - stafflinethickness)); + z11 = z11' + whatever * ne; + x11 = x12; + z12 = directionpoint -ne of pat_top; + z13 = z12 + whatever * ne; + x13 = x1; + z14 = z11 + whatever * ne; + x14 = x1; + + z21' = z4r + whatever * (z1r - z4r); + y21' = -y11' + feta_space_shift; + z21 = z21' + whatever * ne; + x21 = x22; + z22 = directionpoint -ne of pat_bottom; + z23 = z22 + whatever * ne; + x23 = x3; + z24 = z21 + whatever * ne; + x24 = x3; + + fill z11 + -- z12 + -- z13 + -- z14 + -- cycle; + fill z21 + -- z22 + -- z23 + -- z24 + -- cycle; + + penlabels (1, 1', 2, 3, 3', 4); + labels (11, 11', 12, 13, 14, 21, 21', 22, 23, 24); + + if arrowup: + draw_arrow (z1, top_stem_thick * brush_scale_up, + z1'l - z4l, stafflinethickness / 2, false); + fi; + if arrowdown: + draw_arrow (z3, top_stem_thick * brush_scale_down, + z2r - z3'r, stafflinethickness / 2, true); + w := w + extendright; + fi; + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +enddef; + + +fet_beginchar ("Natural", "natural"); + draw_natural (false, false); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Natural (arrow up)", "natural.arrowup"); + draw_natural (true, false); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Natural (arrow down)", "natural.arrowdown"); + draw_natural (false, true); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Natural (arrows up and down)", "natural.arrowboth"); + draw_natural (true, true); +fet_endchar; + + +draw_shifted_too; + + +% +% Dedicated to my mom. (3/10/97) +% +% Mamma, ik hou van je; kom je alsjeblieft terug? +% -- HW +% +% +% TODO: remove crook_fatness +% TODO: document, simplify! +% + +def draw_meta_flat (expr xcenter, w, crook_fatness, arrowup, arrowdown) = + save crook_thinness; + save bottom_overshoot, bot_crook_dir; + save top_stem_thick, top_stem_thick_orig; + save bottom_stem_thick, hair, smaller_hole; + save top_crook_thinness; + save zwiep; + save center; + pair center, bot_crook_dir; + save clearing, clearing_orig; + + clearxy; + + % the stem shouldn't reach the top staff line. + %% TODO: should take from height. + % + % TODO: parameterize this + % + if w >= 0.75 staff_space: + smaller_hole = 0.35 stafflinethickness; + else: + smaller_hole = 0; + fi; + crook_thinness = .7 stafflinethickness + .06 staff_space; + top_crook_thinness = 1 stafflinethickness + .065 staff_space; + clearing = 1.7 stafflinethickness; + clearing_orig = clearing; + if arrowup: + clearing := 0.5 staff_space; + fi; + bottom_overshoot = stafflinethickness; + + bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#; + top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#; + top_stem_thick_orig# = top_stem_thick#; + if arrowup: + % to look nice, arrowed stems should be less brushed + top_stem_thick# := top_stem_thick# * 0.8; + fi; + define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick, + top_stem_thick_orig); + + if odd (top_stem_thick - bottom_stem_thick): + top_stem_thick := top_stem_thick - 1; + fi; + if odd (top_stem_thick_orig - bottom_stem_thick): + top_stem_thick_orig := top_stem_thick_orig - 1; + fi; + + center = (xcenter, 0); + + x1l = hround (xcenter - .5 top_stem_thick); + y1 = vround (2 staff_space - clearing); + x2l = hround (xcenter - .5 bottom_stem_thick); + y2 = -.5 staff_space - .5 stafflinethickness; + % z16 and the `*_orig' variables are needed for arrowed accidentals + % because their inner part should be unchanged from plain ones but + % the points z3l, z3r, and z10 depend on values that are different + % for arrowed accidentals + x16l = hround (xcenter -.5 top_stem_thick_orig); + y16 = vround (2 staff_space - clearing_orig); + + penpos1 (top_stem_thick, 0); + penpos16 (top_stem_thick_orig, 0); + penpos2 (bottom_stem_thick, 0); + + y3l = vfloor ((staff_space - stafflinethickness) / 2); + z3l = whatever [z2r, z1r]; + z3r = .3 [z2r, + (z16r shifted (0, clearing_orig - 1.7 stafflinethickness))] + + (smaller_hole, 0); + x3r := hceiling x3r; + + % we insert z3l to get better conversion with mf2pt1 + fill simple_serif (z1r, z1l, 30) + -- z2l + -- z2r + -- z3l + -- cycle; + + z10 = whatever [z2r, z16r] + (smaller_hole, 0); + y10 = -1/10 staff_space; + x10 := hceiling x10; + + x11 = xcenter + bottom_overshoot / 3; + y11 = -vround (.5 (staff_space + stafflinethickness) + + bottom_overshoot); + + x2a = 0.2[x2r, x7]; + y2a = 1.5[y2, y11]; + + penpos4 (whatever, 53); + + y4l - y4r = top_crook_thinness; + y5r = .15 staff_space; + x5l = hround (w + xcenter); + y4 = staff_space / 2; + x4r = .45 [x5r, x3r]; + y4l := vround y4l; + + penpos5 (crook_fatness, -175); + + bot_crook_dir = unitvector ((x5l, 0) - z11); + z8 = z11 + whatever * bot_crook_dir; + y8 = -staff_space / 2; + + z7 = z8 + + whatever * bot_crook_dir + + crook_thinness * (bot_crook_dir rotated 90); + x7 = .1 [x3r, x8]; + + unfill z3r{z3r - z10} + .. z4r{right} + .. z5r{down} + .. z7{-bot_crook_dir} + & z7 + .. z10{z3r - z10} + -- cycle; + + if arrowdown: + fill z2l{down} + .. z2a{up} + .. z8{bot_crook_dir} + .. z5l{up} + .. z4l{left} + .. z3l + -- cycle; + else: + fill z2l{down} + .. z11{right} + .. z8{bot_crook_dir} + .. z5l{up} + .. z4l{left} + .. z3l + -- cycle; + fi; + + if arrowup: + draw_arrow (z1, top_stem_thick, z1l - z2l, + 0.5 stafflinethickness, false); + fi; + if arrowdown: + draw_arrow ((0.5 [x2l, x2a], y2), x2a - x2l, up, + staff_space / 2, true); + fi; +enddef; + + +def draw_arrowed_meta_flat (expr xcenter, width, crook_fatness, + arrowup, arrowdown) = + save depth, height, extendleft; + + depth# = 0.6 staff_space#; + height# = 1.9 staff_space#; + extendleft# := 1.2 stafflinethickness#; + if arrowup: + extendleft# := 3.45 stafflinethickness#; + height# := height# + 0.8 staff_space#; + fi; + if arrowdown: + extendleft# := 3.45 stafflinethickness#; + depth# := depth# + 1.6 staff_space#; + fi; + + set_char_box (extendleft#, width, depth#, height#); + draw_meta_flat(xcenter, w, crook_fatness, arrowup, arrowdown); +enddef; + +% +% unfortunately, 600dpi is not enough to show the brush of the stem. +% + +fet_beginchar ("Flat", "flat"); + draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space, + false, false); + penlabels (range 0 thru 11); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Flat (arrow up)", "flat.arrowup"); + draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space, + true, false); + penlabels (range 0 thru 23); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Flat (arrow down)", "flat.arrowdown"); + draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space, + false, true); + penlabels (range 0 thru 23); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Arrowed Flat (arrow up and down)", "flat.arrowboth"); + draw_arrowed_meta_flat (0, 0.8 staff_space#, 0.31 staff_space, + true, true); + penlabels (range 0 thru 23); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Flat (slashed)", "flat.slash"); + set_char_box (.4 staff_space#, .8 staff_space#, + 0.6 staff_space#, 1.9 staff_space#); + + draw_meta_flat (0, w, 0.31 staff_space, false, false); + + clearxy; + + save slope, slash_width; + slope = 0.5; + slash_width = w; + + z11 = (0, h / 2); + z12 = z11 - (slash_width, slash_width * slope) / 2; + z13 = z11 + (slash_width, slash_width * slope) / 2; + penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90); + penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90); + + z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12); + z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12); + + fill z13r + .. z15 + .. z13l + -- z12l + .. z14 + .. z12r + -- z13r + .. cycle; + + penlabels (12, 13); + labels (14, 15); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Flat (slashed twice)", "flat.slashslash"); + set_char_box (.4 staff_space#, .8 staff_space#, + 0.6 staff_space#, 1.9 staff_space#); + + draw_meta_flat (0, w, 0.31 staff_space, false, false); + + clearxy; + + save slope, slash_width; + slope = 0.5; + slash_width = w; + + z11 = (0, 5/12 h); + z12 = z11 - (slash_width, slash_width * slope) / 2; + z13 = z11 + (slash_width, slash_width * slope) / 2; + penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90); + penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90); + + z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12); + z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12); + + fill z13r + .. z15 + .. z13l + -- z12l + .. z14 + .. z12r + -- z13r + .. cycle; + + penlabels (12, 13); + labels (14, 15); + + z21 = (0, 2/3 h); + z22 = z21 - (slash_width, slash_width * slope) / 2; + z23 = z21 + (slash_width, slash_width * slope) / 2; + penpos22 (1.5 stafflinethickness, angle (z23 - z22) - 90); + penpos23 (1.5 stafflinethickness, angle (z23 - z22) - 90); + + z24 = z22 - .75 stafflinethickness * unitvector (z23 - z22); + z25 = z23 + .75 stafflinethickness * unitvector (z23 - z22); + + fill z23r + .. z25 + .. z23l + -- z22l + .. z24 + .. z22r + -- z23r + .. cycle; + + penlabels (22, 23); + labels (24, 25); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +fet_beginchar ("Flatflat (mirrored)", "mirroredflat.flat"); + set_char_box (0, 1.6 staff_space#, + 0.6 staff_space#, 1.9 staff_space#); + + % This is a modified version of `draw_meta_flat'. + + save crook_thinness, crook_fatness; + save bottom_overshoot, bot_crook_dir; + save top_stem_thick, bottom_stem_thick, hair, smaller_hole; + save top_crook_thinness; + save zwiep; + save center; + pair center, bot_crook_dir; + save clearing, wid; + save pat; + path pat; + + clearxy; + + wid = w / 2; + + % the stem shouldn't reach the top staff line. + %% TODO: should take from height. + % + % TODO: parameterize this + % + if wid >= 0.75 staff_space: + smaller_hole = 0.35 stafflinethickness; + else: + smaller_hole = 0; + fi; + clearing = 1.7 stafflinethickness; + crook_thinness = .7 stafflinethickness + .06 staff_space; + crook_fatness = 0.31 staff_space; + top_crook_thinness = 1 stafflinethickness + .065 staff_space; + bottom_overshoot = stafflinethickness; + + bottom_stem_thick# = 0.06 staff_space# + 0.6 stafflinethickness#; + top_stem_thick# = 0.1 staff_space# + 1.2 stafflinethickness#; + define_whole_blacker_pixels (bottom_stem_thick, top_stem_thick); + + if odd (top_stem_thick - bottom_stem_thick): + top_stem_thick := top_stem_thick - 1; + fi; + + center = (0, 0); + + x1l = hround (-.5 top_stem_thick); + y1 = vround (2 staff_space - clearing); + x2l = hround (-.5 bottom_stem_thick); + y2 = -.5 staff_space - .5 stafflinethickness; + + penpos1 (top_stem_thick, 0); + penpos2 (bottom_stem_thick, 0); + + y3l = vfloor ((staff_space - stafflinethickness) / 2); + z3l = whatever [z2r, z1r]; + z3r = .3 [z2r, z1r] + (smaller_hole, 0); + x3r := hceiling x3r; + + z10 = whatever [z2r, z1r] + (smaller_hole, 0); + y10 = -1/10 staff_space; + x10 := hceiling x10; + + x11 = bottom_overshoot / 3; + y11 = -vround (.5 (staff_space + stafflinethickness) + + bottom_overshoot); + + penpos4 (whatever, 53); + + y4l - y4r = top_crook_thinness; + y5r = .15 staff_space; + x5l = hround (wid); + y4 = staff_space / 2; + x4r = .45 [x5r, x3r]; + y4l := vround y4l; + + penpos5 (crook_fatness, -175); + + bot_crook_dir = unitvector ((x5l, 0) - z11); + z8 = z11 + whatever * bot_crook_dir; + y8 = -staff_space / 2; + + z7 = z8 + + whatever * bot_crook_dir + + crook_thinness * (bot_crook_dir rotated 90); + x7 = .1 [x3r, x8]; + + pat := z3r{z3r - z10} + .. z4r{right} + .. z5r{down} + .. z7{-bot_crook_dir} + & z7 + .. z10{z3r - z10} + -- cycle; + unfill pat; + unfill pat xscaled -1; + + pat := z11{right} + .. z8{bot_crook_dir} + .. z5l{up} + .. z4l{left} + .. z3l; + fill pat + -- simple_serif (z1r, z1l, 30) + -- reverse pat xscaled -1 shifted (-feta_eps, 0) + -- cycle; + + currentpicture := currentpicture shifted (w/2, 0); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Semi flat", "mirroredflat"); + set_char_box (1.2 stafflinethickness#, .8 staff_space#, + 0.6 staff_space#, 1.9 staff_space#); + + draw_meta_flat (0, w, 0.31 staff_space, false, false); + currentpicture := currentpicture xscaled -1 shifted (w - b, 0); +fet_endchar; + + +fet_beginchar ("Semi flat", "mirroredflat.backslash"); + set_char_box (.4 staff_space#, .8 staff_space#, + 0.6 staff_space#, 1.9 staff_space#); + + draw_meta_flat (0, w, 0.31 staff_space, false, false); + + clearxy; + + save slope, slash_width; + slope = 0.5; + slash_width = w; + + z11 = (0, h / 2); + z12 = z11 - (slash_width, slash_width * slope) / 2; + z13 = z11 + (slash_width, slash_width * slope) / 2; + penpos12 (1.5 stafflinethickness, angle (z13 - z12) - 90); + penpos13 (1.5 stafflinethickness, angle (z13 - z12) - 90); + + z14 = z12 - .75 stafflinethickness * unitvector (z13 - z12); + z15 = z13 + .75 stafflinethickness * unitvector (z13 - z12); + + fill z13r + .. z15 + .. z13l + -- z12l + .. z14 + .. z12r + -- z13r + .. cycle; + + currentpicture := currentpicture xscaled -1 shifted (w - b, 0); + + labels (1, 2, 3); +fet_endchar; + + +fet_beginchar ("Double Flat", "flatflat"); + save left_wid, overlap, right_wid; + + left_wid = .7; + right_wid = .8; + overlap = .05; + + set_char_box (1.2 stafflinethickness#, + (left_wid + right_wid - overlap) * staff_space#, + .6 staff_space#, 1.9 staff_space#); + draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space, + false, false); + draw_meta_flat (hround ((left_wid - overlap) * staff_space), + right_wid * staff_space, 1/3 staff_space, + false, false); +fet_endchar; + + +fet_beginchar ("3/4 Flat", "flatflat.slash"); + save left_wid, overlap, right_wid; + + left_wid = .7; + right_wid = .8; + overlap = .05; + + set_char_box (1.2 stafflinethickness#, + (left_wid + right_wid - overlap) * staff_space#, + .6 staff_space#, 1.9 staff_space#); + draw_meta_flat (0, left_wid * staff_space, 1/3 staff_space, + false, false); + draw_meta_flat (hround ((left_wid - overlap) * staff_space), + right_wid * staff_space, 1/3 staff_space, + false, false); + + %% maybe we should clip part of the stems? + %% or make the 1st flat smaller? + %% or reverse it? + pickup pencircle scaled 2 stafflinethickness; + + z12 = round (-.25 w - b, .55 staff_space) + feta_offset; + z13 = round (.75 w, 1.45 staff_space) + feta_offset; + penpos12 (2 stafflinethickness, angle (z13 - z12) - 90); + penpos13 (2 stafflinethickness, angle (z13 - z12) - 90); + + z14 = z12 - stafflinethickness * unitvector (z13 - z12); + z15 = z13 + stafflinethickness * unitvector (z13 - z12); + + fill z13r + .. z15 + .. z13l + -- z12l + .. z14 + .. z12r + -- z13r + .. cycle; + + penlabels (12, 13); + labels (14, 15); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Double Sharp", "doublesharp"); + save klaverblad, klaversteel; + save pat; + path pat; + + klaversteel = 1/15 staff_space; + klaverblad = .4 staff_space - .5 stafflinethickness; + + set_char_box (0, staff_space#, .5 staff_space#, .5 staff_space#); + + z1 = (klaversteel, 0); + z2 = (w / 2 - klaverblad / 10, h - klaverblad); + z3 = (w / 2, h); + z4 = z2 reflectedabout ((0, 0), (1, 1)); + z5 = z1 reflectedabout ((0, 0), (1, 1)); + + labels (1, 2, 3, 4, 5); + + pickup pencircle scaled blot_diameter; + + x2 := hfloor (rt x2) - blot_diameter / 2; + x3 := hfloor (rt x3) - blot_diameter / 2; + y3 := vfloor (top y3) - blot_diameter / 2; + y4 := vfloor (top y4) - blot_diameter / 2; + + pat = (rt z1){dir45} + .. {right}(bot z2) + .. rt z2 + -- rt z3{z3 - z2} + .. top z3{z4 - z3} + -- top z4{z4 - z3} + .. (lft z4){down} + .. {dir 225}(top z5); + pat := pat + -- reverse pat xscaled -1 shifted (-feta_eps, 0); + + % assure symmetry -- it's more important to center the glyph on the + % staff line than centering it between staff lines, so we use + % feta_shift, not feta_space_shift. + h := h + feta_shift; + + fill pat shifted (0, feta_shift) + -- reverse pat yscaled -1 shifted (0, -feta_eps) + -- cycle; + + % ugh + currentpicture := currentpicture shifted (hround (w / 2), 0); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +def draw_paren = + save leftindent; + + leftindent := .2 staff_space; + + set_char_box (0, .5 staff_space# + stafflinethickness#, + staff_space#, staff_space#); + + d := d - feta_shift; + + z1 = (leftindent, h); + z2 = (w - stafflinethickness, .5 (h - d)); + z3 = (leftindent, -d); + + penpos1 (stafflinethickness, 35); + penpos2 (.1 staff_space + stafflinethickness, 0); + penpos3 (stafflinethickness, -35); + + fill z2l{down} + .. simple_serif (z3l, z3r, 90) + .. z2r{up} + .. simple_serif (z1r, z1l, 90) + .. z2l{down} + -- cycle; +enddef; + + +fet_beginchar ("Right Parenthesis", "rightparen"); + draw_paren; + penlabels (1, 2, 3); + + remember_pic := currentpicture; + + draw_staff (-2, 2, 0); +fet_endchar; + + +draw_shifted_too; + + +fet_beginchar ("Left Parenthesis", "leftparen"); + draw_paren; + + currentpicture := currentpicture xscaled -1; + + set_char_box (charwd, charbp, chardp, charht); +fet_endchar; + +fet_endgroup ("accidentals"); diff --git a/muse2/share/scoreglyphs/feta-original/feta11.mf b/muse2/share/scoreglyphs/feta-original/feta11.mf new file mode 100644 index 00000000..be6a6a7e --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta11.mf @@ -0,0 +1,13 @@ +% feta11.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 11.22; +test := 0; + + +input feta-generic; + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta13.mf b/muse2/share/scoreglyphs/feta-original/feta13.mf new file mode 100644 index 00000000..5014c123 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta13.mf @@ -0,0 +1,13 @@ +% feta13.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 12.60; +test := 0; + + +input feta-generic; + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta14.mf b/muse2/share/scoreglyphs/feta-original/feta14.mf new file mode 100644 index 00000000..23ac8e4d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta14.mf @@ -0,0 +1,14 @@ +% feta14.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 14.14; +test := 0; + + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta16.mf b/muse2/share/scoreglyphs/feta-original/feta16.mf new file mode 100644 index 00000000..174460b7 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta16.mf @@ -0,0 +1,13 @@ +% feta16.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 15.87; +test := 0; + + +input feta-generic; + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta18.mf b/muse2/share/scoreglyphs/feta-original/feta18.mf new file mode 100644 index 00000000..b52f6a3e --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta18.mf @@ -0,0 +1,14 @@ +% feta18.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +% todo change file name +design_size := 17.82; +test := 0; + + +input feta-generic; + + +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta20.mf b/muse2/share/scoreglyphs/feta-original/feta20.mf new file mode 100644 index 00000000..2b561b20 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta20.mf @@ -0,0 +1,14 @@ +% feta20.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 20; + +input feta-autometric; + + +% use feta-test for debugging. +test := 0; +input feta-generic; + + +end. diff --git a/muse2/share/scoreglyphs/feta-original/feta23.mf b/muse2/share/scoreglyphs/feta-original/feta23.mf new file mode 100644 index 00000000..d2cf0025 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta23.mf @@ -0,0 +1,15 @@ +% feta23.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +% todo change file name +design_size := 22.45; +test := 0; + + +input feta-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/feta26.mf b/muse2/share/scoreglyphs/feta-original/feta26.mf new file mode 100644 index 00000000..2bfa5366 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/feta26.mf @@ -0,0 +1,15 @@ +% feta26.mf +% part of LilyPond's pretty-but-neat music font + +input feta-autometric; + +design_size := 25.20; +test := 0; + + +input feta-generic; + + +end. + + diff --git a/muse2/share/scoreglyphs/feta-original/mf2pt1.mp b/muse2/share/scoreglyphs/feta-original/mf2pt1.mp new file mode 100644 index 00000000..a8b45aad --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/mf2pt1.mp @@ -0,0 +1,495 @@ +%%%% +%%%% MF2PT1.MP, by Scott Pakin, scott+mf@pakin.org +%%%% +%%%% This file is used to dump a special version of MetaPost with: +%%%% mpost -progname=mpost -ini mf2pt1 \\dump +%%%% +%%%% To pretty-print this file, you'll need LaTeX and the mftinc package +%%%% (available from CTAN). +%%%% + +%%%% ==================================================================== %%%% +%%%% mf2pt1 %%%% +%%%% Copyright (C) 2008 Scott Pakin %%%% +%%%% %%%% +%%%% This program may be distributed and/or modified under the conditions %%%% +%%%% of the LaTeX Project Public License, either version 1.3c of this %%%% +%%%% license or (at your option) any later version. %%%% +%%%% %%%% +%%%% The latest version of this license is in: %%%% +%%%% %%%% +%%%% http://www.latex-project.org/lppl.txt %%%% +%%%% %%%% +%%%% and version 1.3c or later is part of all distributions of LaTeX %%%% +%%%% version 2006/05/20 or later. %%%% +%%%% ==================================================================== %%%% + +input mfplain; + +%%% addto makepath makepen +%%% length clockwise counterclockwise +%%% scaled dashed withcolor + +%% \begin{explaincode} +%% Enable a \MF\ file to determine if it's being built with +%% \texttt{mf2pt1}. +%% \end{explaincode} + +newinternal ps_output; +ps_output := 1; + + +%% \begin{explaincode} +%% The following was taken right out of \texttt{mfplain.mp}. The \mfcomment +% |def| and the |special|s at the end +%% are the sole additions. Normally, MetaPost outputs a tight bounding +%% box around the character in its PostScript output. The purpose of the +%% first \mfcomment +% |special| +%% is to pass \texttt{mf2pt1} a bounding box that includes the proper +%% surrounding whitespace. The purpose of the second special is to +%% provide \texttt{mf2pt1} with a default PostScript font name. +%% \end{explaincode} + +def beginchar(expr c,w_sharp,h_sharp,d_sharp) = + begingroup + charcode:=if known c: byte c else: 0 fi; + charwd:=w_sharp; charht:=h_sharp; chardp:=d_sharp; + w:=charwd*pt; h:=charht*pt; d:=chardp*pt; + charic:=0; clearxy; clearit; clearpen; scantokens extra_beginchar; + + def to_bp (expr num) = decimal (ceiling (num*bp_per_pixel)) enddef; + special "% MF2PT1: glyph_dimensions 0 " & to_bp (-d) & " " & to_bp(w) & " " & to_bp(h); + special "% MF2PT1: font_size " & decimal designsize; + special "% MF2PT1: font_slant " & decimal font_slant_; + special "% MF2PT1: charwd " & decimal charwd; % Must come after the |font_size| |special| + for fvar = "font_identifier", "font_coding_scheme", "font_version", + "font_comment", "font_family", "font_weight", "font_unique_id", + "font_name": + if known scantokens (fvar & "_"): + special "% MF2PT1: " & fvar & " " & scantokens (fvar & "_"); + fi; + endfor; + for fvar = "font_underline_position", "font_underline_thickness": + if known scantokens (fvar & "_"): + special "% MF2PT1: " & fvar & " " & + scantokens ("decimal " & fvar & "_"); + fi; + endfor; + special "% MF2PT1: font_fixed_pitch " & + (if font_fixed_pitch_: "1" else: "0" fi); +enddef; + + +%% \begin{explaincode} +%% Enable a character to specify explicitly the PostScript glyph +%% name associated with it. +%% \end{explaincode} +def glyph_name expr name = + special "% MF2PT1: glyph_name " & name; +enddef; + + +%% \begin{explaincode} +%% Store the value of \mfcomment +% |font_slant_|, so we can recall it at each |beginchar|. +%% \end{explaincode} + +font_slant_ := 0; + +def font_slant expr x = + font_slant_ := x; + fontdimen 1: x +enddef; + + +%% \begin{explaincode} +%% Redefine \mfcomment +% |bpppix_|, the number of ``big'' points per pixel. \mfcomment +% This in turn redefines |mm|, |in|, |pt|, and other derived units. +%% \end{explaincode} + +def bpppix expr x = + bpppix_ := x; + mm := 2.83464 / bpppix_; + pt := 0.99626 / bpppix_; + dd := 1.06601 / bpppix_; + bp := 1 / bpppix_; + cm := 28.34645 / bpppix_; + pc := 11.95517 / bpppix_; + cc := 12.79213 / bpppix_; + in := 72 / bpppix_; + hppp := pt; + vppp := pt; +enddef; + + +%% \begin{explaincode} +%% Define a bunch of PostScript font parameters to be used by +%% \texttt{mf2pt1.pl}. Default values are specified in +%% \texttt{mf2pt1.pl}, not here. +%% \end{explaincode} + +forsuffixes fvar = font_version, font_comment, font_family, font_weight, + font_name, font_unique_id: + scantokens ("string " & str fvar & "_;"); + scantokens ("def " & str fvar & " expr x = " & str fvar & "_ := x enddef;"); +endfor; + +forsuffixes fvar = font_underline_position, font_underline_thickness: + scantokens ("numeric " & str fvar & "_;"); + scantokens ("def " & str fvar & " expr x = " & str fvar & "_ := x enddef;"); +endfor; + +boolean font_fixed_pitch_; +font_fixed_pitch_ := false; +def font_fixed_pitch expr x = font_fixed_pitch_ := x enddef; + + +%% \begin{explaincode} +%% We'd like to be able to use calligraphic pens. Normally, MetaPost's +%% output routine does all the work for us of converting these to filled +%% PostScript paths. The only exception occurs for paths drawn using a +%% pen that was transformed from \mfcomment +% |pencircle|. MetaPost outputs these paths as stroked PostScript +%% paths. The following code tricks MetaPost into using a filled path +%% for \mfcomment +% |pencircle| by replacing the primitive |pencircle| pen with a +%% non-primitive approximation. Note that we use a 20-gon for our circle +%% instead of a diamond, so we get better results from \mfcomment +% |draw|. +%% \end{explaincode} + +pen fakepencircle, mfplain_pencircle; +mfplain_pencircle := pencircle; +fakepencircle := makepen (for deg=0 step 360/20 until 359: + (0.5 cosd deg, 0.5 sind deg)-- + endfor cycle); +save pencircle; +pen pencircle; +pencircle := fakepencircle; + + +%% \begin{explaincode} +%% Return \mfcomment +% |true| if a path is cyclic, |false| otherwise. +%% \end{explaincode} + +def is_cyclic expr cpath = + (point 0 of cpath = point (length cpath) of cpath) +enddef; + + +%% \begin{explaincode} +%% Determine the direction of a path which doesn't intersect +%% itself. \mfcomment +% Returns |true| if the curve is clockwise, |false| if +%% counterclockwise. For non-cyclic paths the result is not +%% predictable. +%% \bigskip +%% +%% The \mfcomment +% |crossproduct|, |makeline|, and |is_clockwise| functions were +%% provided by Werner Lemberg. +%% \bigskip +%% +%% The algorithm used is quite simple: +%% +%% \begin{itemize} +%% \item Find a point~$P$ on the path which has a non-zero direction, +%% and which is on a not-too-short path element. +%% +%% \item Construct a ray of ``infinite'' length, starting in the +%% vicinity of~$P$ which intersects the path at this point. +%% +%% \item Use \mfcomment +% |intersectiontimes| to find the intersection. If the direction of +%% the path at this point is (near) zero, or if we have a grazing +%% intersection or even a tangent, get a new ray. +%% +%% \item Shorten the ray so that it starts right after the +%% intersection. Repeat the previous step until no intersection is +%% found. Then go back to the last intersection and compare the path's +%% direction with the direction of the ray. According to the +%% \emph{nonzero winding number} rule we have found a clockwise +%% oriented path if it crosses the ray from left to right. +%% \end{itemize} +%% +%% This method completely avoids any problems with the geometry of +%% B\'{e}zier curves. If problems arise, a different ray is tried. +%% Since it isn't necessary to analyze the whole path it runs quite fast +%% in spite of using \mfcomment +% |intersectiontimes| which is a slow MetaPost command. +%% \end{explaincode} + +vardef crossproduct (expr u, v) = + save u_, v_; + pair u_, v_; + + u_ := unitvector u; + v_ := unitvector v; + + abs (xpart u_ * ypart v_ - ypart u_ * xpart v_) +enddef; + +vardef makeline primary p = + save start, bad_n, loop, distance, d, i, n; + pair start, d; + + loop := 0; + bad_n := -1; + for i := 0 step 1 until length p - 1: + distance := length (point i of p - point (i + 1) of p); + if distance <> 0: + if distance < 1: + % In case we don't find something better. + bad_n := i; + else: + n := i; + loop := 1; + fi; + fi; + exitif loop = 1; + endfor; + + if loop = 0: + if bad_n <> -1: + n := bad_n; + loop = 1; + fi; + fi; + + % Add some randomness to get different lines for each function call. + n := n + uniformdeviate 0.8 + 0.1; + start := point n of p; + + if loop = 0: + % Construct a line which misses the degenerated path. + start + (1, 0) + -- start + (1, 1) + else: + d := direction n of p; + + % Again, some added randomness. + n := uniformdeviate 150 + 15; + d := unitvector (d rotated n); + + % Construct a line which intersects the path at least once. + start - eps * d + -- infinity * d + fi +enddef; + +vardef is_clockwise primary p = + save line, cut, cut_new, res, line_dir, tangent_dir; + path line; + pair cut, cut_new, line_dir, tangent_dir; + + line := makeline p; + line_dir := direction 0 of line; + + % Find the outermost intersection. + cut := (0, 0); + forever: + cut_new := line intersectiontimes p; + exitif cut_new = (-1, -1); + + % Compute a new line if we have a strange intersection. + tangent_dir := direction (ypart cut_new) of p; + if abs tangent_dir < eps: + % The vector is zero or too small. + line := makeline p; + line_dir := direction 0 of line; + + elseif abs (ypart cut_new - floor (ypart cut_new + 0.5)) < eps: + % Avoid possible tangent touching in a corner or cusp. + line := makeline p; + line_dir := direction 0 of line; + + elseif crossproduct (tangent_dir, line_dir) < 0.2: + % Grazing intersection (arcsin 0.2 ~= 11.5 degrees). + line := makeline p; + line_dir := direction 0 of line; + + else: + % Go ahead. + cut := cut_new; + line := subpath (xpart cut + eps, infinity) of line; + fi; + endfor; + + tangent_dir := direction (ypart cut) of p; + if tangent_dir <> (0, 0): + res := (angle tangent_dir - angle line_dir + 180) mod 360 - 180; + res < 0 + else: + false + fi +enddef; + + +%% \begin{explaincode} +%% Make a given path run clockwise or counterclockwise. \mfcomment +% (|counterclockwise| is defined by \texttt{mfplain} but we override +%% it here.) +%% \end{explaincode} + +vardef counterclockwise primary c = + (if is_clockwise c: (reverse c) else: c fi) +enddef; + +vardef clockwise primary c = + (if is_clockwise c: c else: (reverse c) fi) +enddef; + + +%% \begin{explaincode} +%% Redefine \mfcomment +% |fill| and |unfill| to ensure that filled paths run +%% counterclockwise and unfilled paths run clockwise, as is required +%% by PostScript Type~1 fonts. +%% \end{explaincode} + +def fill expr c = + addto currentpicture contour counterclockwise c t_ pc_ +enddef; + +def unfill expr c = + addto currentpicture contour clockwise c t_ pc_ withcolor background +enddef; + + +%% \begin{explaincode} +%% Convert \mfcomment +% |filldraw| and |unfilldraw| to |fill| and |unfill|. +%% \end{explaincode} + +let mfplain_filldraw := filldraw; +def filldraw expr c = + begingroup + message "! Warning: Replacing filldraw with fill."; + fill c + endgroup +enddef; + +let mfplain_unfilldraw := unfilldraw; +def unfilldraw expr c = + begingroup + message "! Warning: Replacing unfilldraw with unfill."; + unfill c + endgroup +enddef; + + +%% \begin{explaincode} +%% Return \mfcomment +% |true| if |currentpen| looks like a |pencircle|. +%% \end{explaincode} + +def using_pencircle = + begingroup + path qpath, circlepath; + qpath = makepath currentpen; + numeric circlediv; + circlepath = makepath pencircle; + circlediv = xpart (lrcorner circlepath); + + (length qpath = length circlepath) and (pen_rt <> 0) and (pen_top <> 0) + for pp = 0 upto (length qpath)-1: + and ((xpart (point pp of qpath) / pen_rt, + ypart (point pp of qpath) / pen_top) = + point pp of circlepath / circlediv) + endfor + endgroup +enddef; + + +%% \begin{explaincode} +%% If the pen looks like a circular pen, draw a nice circle. Otherwise, +%% draw the pen as is. +%% \end{explaincode} + +def drawdot expr z = + if using_pencircle: + begingroup + path cpath; + numeric clength; + cpath = makepath currentpen; + clength = length cpath; + fill ((point 0 of cpath) + ..(point clength/4 of cpath) + ..(point clength/2 of cpath) + ..(point 3*clength/4 of cpath) + ..cycle) shifted z t_ + endgroup + else: + addto currentpicture contour makepath currentpen shifted z + t_ pc_ + fi +enddef; + + +%% \begin{explaincode} +%% Do the same as the above, but unfill the current pen. +%% \end{explaincode} + +def undrawdot expr z = + if using_pencircle: + begingroup + path cpath; + numeric clength; + cpath = makepath currentpen; + clength = length cpath; + unfill ((point 0 of cpath) + ..(point clength/4 of cpath) + ..(point clength/2 of cpath) + ..(point 3*clength/4 of cpath) + ..cycle) shifted z t_ + endgroup + else: + unfill makepath currentpen shifted z t_ + fi +enddef; + + +%% \begin{explaincode} +%% MetaPost renders \mfcomment +% |draw| with a filled curve. +%% Hence, we need to ensure the orientation is correct (i.e., +%% counterclockwise). Unfortunately, we have no way to check for +%% overlap, and it's fairly common for MetaPost to output +%% self-overlapping curve outlines, even if the curve itself has no +%% overlap. +%% \end{explaincode} + +def draw expr p = + addto currentpicture + if picture p: + also p + elseif is_cyclic p: + doublepath counterclockwise p t_ withpen currentpen + else: + if is_clockwise (p--cycle): + doublepath (reverse p) t_ withpen currentpen + else: + doublepath p t_ withpen currentpen + fi + fi + pc_ +enddef; + +def undraw expr p = + addto currentpicture + if picture p: + also p + elseif is_cyclic p: + doublepath clockwise p t_ withpen currentpen + else: + if is_clockwise (p--cycle): + doublepath p t_ withpen currentpen + else: + doublepath (reverse p) t_ withpen currentpen + fi + fi + pc_ withcolor background +enddef; diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-accidentals.mf b/muse2/share/scoreglyphs/feta-original/parmesan-accidentals.mf new file mode 100644 index 00000000..b5fe6630 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-accidentals.mf @@ -0,0 +1,385 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-accidentals.mf -- implement ancient accidentals +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("accidentals"); + + +%%%%%%%% +% +% +% +% EDITIO MEDICAEA +% +% +% +fet_beginchar ("Ed. Med. Flat" , "medicaeaM1"); + set_char_box (0.1 staff_space#, 0.6 staff_space#, + 0.6 staff_space#, 1.0 staff_space#); + + save ellipse, pat, outline, T; + path ellipse, pat, outline; + transform T; + + T := identity xscaled 0.50 linethickness + yscaled 0.22 staff_space; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + x1 = x2 = 0; + top y1 = h; + bot y2 = -d; + + fill get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, up, z2) + -- cycle; + + T := identity xscaled 0.50 linethickness + yscaled 0.22 staff_space + rotated -63; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z3 = (0.10 staff_space, -0.50 staff_space); + z4 = (0.40 staff_space, +0.40 staff_space); + z5 = (0.10 staff_space, +0.40 staff_space); + + pat := z3{(1, 2)} + .. z4 + .. z5{(-1, -1)}; + + % the original envelope curve created with `draw' contains + % cusps which we avoid + outline := get_subpath (ellipse, -direction 0 of pat, + direction 0 of pat, z3) + .. get_subpoint (ellipse, direction 1 of pat, z4) + .. get_subpath (ellipse, direction 2 of pat, + -direction 1.8 of pat, z5) + .. get_subpoint (ellipse, -direction 1 of pat, z4) + {-direction 1 of pat} + .. cycle; + + save shift; + pair shift; + + % make the outline touch the bounding box + shift = find_tangent_shift (((w, -d) -- (w, h)), outline, + (b, 0), (-b, 0)); + outline := outline shifted shift; + + fill outline; + + labels (1, 2, 3, 4, 5); +fet_endchar; + + +%%%%%%%% +% +% +% +% EDITIO VATICANA +% +% +% +fet_beginchar ("Ed. Vat. Flat" , "vaticanaM1"); + z1 = (0.00 staff_space, +0.80 staff_space); + z2 = (0.00 staff_space, -0.08 staff_space); + z3 = (0.25 staff_space, -0.23 staff_space); + z4 = (0.50 staff_space, -0.24 staff_space); + z5 = (0.50 staff_space, +0.03 staff_space); + z6 = (0.25 staff_space, +0.20 staff_space); + z7 = (0.15 staff_space, +0.26 staff_space); + + save pat, ellipse, T; + path pat, ellipse; + transform T; + + T := identity xscaled 0.50 linethickness + yscaled 0.22 staff_space; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + pat := z1 + -- z2{down} + ... z3 + ... {up}z4 + -- z5{up} + .. z6 + .. z7; + + % the original envelope curve created with `draw' contains + % cusps which we avoid + fill get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, direction 1.1 of pat, z2) + ... bot z3 + ... get_subpath (ellipse, direction 2.9 of pat, up, z4) + -- get_subpath (ellipse, up, direction 4.1 of pat, z5) + .. top z6 + .. get_subpath (ellipse, + direction 6 of pat, -direction 6 of pat, z7) + .. bot z6 + .. {down}bot lft z5 + -- top lft z4{down} + ... top z3 + ... top rt z2{up} + -- cycle; + + set_char_box (0.00 staff_space# + 0.25 linethickness#, + 0.50 staff_space# + 0.25 linethickness#, + 0.23 staff_space# + 0.11 staff_space#, + 0.80 staff_space# + 0.11 staff_space#); + + labels (1, 2, 3, 4, 5, 6, 7); +fet_endchar; + + +fet_beginchar ("Ed. Vat. Natural" , "vaticana0"); + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled 0.80 linethickness + yscaled 0.22 staff_space; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z1 = (0.00 staff_space, +0.65 staff_space); + z2 = (0.00 staff_space, -0.35 staff_space); + + fill get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, up, z2) + -- cycle; + + pickup penrazor scaled 0.22 staff_space + rotated 90; + + z3 = (0.00 staff_space, -0.30 staff_space); + z4 = (0.40 staff_space, -0.08 staff_space); + + draw z3 + -- z4; + + addto currentpicture also currentpicture + xscaled -1 + yscaled -1 + shifted (0.40 staff_space, 0.0 staff_space); + + set_char_box (0.00 staff_space# + 0.40 linethickness#, + 0.40 staff_space# + 0.40 linethickness#, + 0.65 staff_space# + 0.11 staff_space#, + 0.65 staff_space# + 0.11 staff_space#); + + labels (1, 2, 3, 4); +fet_endchar; + + +%%%%%%%% +% +% +% +% MENSURAL NOTATION +% +% +% +fet_beginchar ("Mensural Sharp" , "mensural1"); + save stemthick; + + define_pixels (stemthick); + + stemthick# = linethickness#; + + save circle, pat, T; + path circle, pat; + transform T; + + T := identity scaled 0.8 stemthick; + pickup pencircle transformed T; + circle := fullcircle transformed T; + + z1 = 0.4 staff_space * (0.8, 1); + z1 = -z2; + + pat := get_subpath (circle, z1 - z2, z2 - z1, z1) + -- get_subpath (circle, z2 - z1, z1 - z2, z2) + -- cycle; + + fill pat; + fill pat xscaled -1; + fill pat shifted (0.20 staff_space, 0); + fill pat xscaled -1 shifted (0.20 staff_space, 0); + + set_char_box (0.8 * 0.4 staff_space# + 0.4 stemthick#, + (0.8 * 0.4 + 0.2) * staff_space# + 0.4 stemthick#, + 0.4 staff_space# + 0.4 stemthick#, + 0.4 staff_space# + 0.4 stemthick#); + + labels (1, 2); +fet_endchar; + + +fet_beginchar ("Mensural Flat" , "mensuralM1"); + save stemthick; + + define_pixels (stemthick); + + stemthick# = linethickness#; + + save ellipse, pat, outline, T; + path ellipse, pat, outline; + transform T; + + T := identity xscaled 1.4 stemthick + yscaled 0.6 stemthick + rotated 45; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z1 = (0.00 staff_space, +1.80 staff_space); + z2 = (0.00 staff_space, -0.25 staff_space); + z3 = (0.35 staff_space, -0.25 staff_space); + z4 = (0.35 staff_space, +0.25 staff_space); + z5 = (0.00 staff_space, +0.25 staff_space); + + pat := z2 + .. z3 + .. z4 + .. z5; + + save dirs, s; + pair dirs[]; + + s := 1/4; + + % we approximate `draw pat' + for i = 2 step s until (length pat + 2): + dirs[i] := direction (i - 2) of pat; + endfor; + + outline := get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, dirs2, z2) + for i = (2 + s) step s until (length pat + 2 - s): + .. get_subpoint (ellipse, dirs[i], + point (i - 2) of pat) + endfor + .. top z5 + -- bot z5 + for i = (length pat + 2 - s) step -s until 2: + .. get_subpoint (ellipse, -dirs[i], + point (i - 2) of pat) + endfor + -- get_subpoint (ellipse, up, z2) + -- cycle; + + fill outline; + + set_char_box (0.00 staff_space# + 0.75 stemthick#, + 0.40 staff_space# + 0.75 stemthick#, + 0.25 staff_space# + 0.75 stemthick#, + 1.80 staff_space# + 0.75 stemthick#); + + labels (1, 2, 3, 4, 5); +fet_endchar; + + +fet_beginchar ("Hufnagel Flat" , "hufnagelM1"); + save stemthick; + + define_pixels (stemthick); + + stemthick# = linethickness#; + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 2.4 stemthick + yscaled 0.4 stemthick + rotated 45; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z1 = (0.00 staff_space, +1.80 staff_space); + z2 = (0.00 staff_space, -0.15 staff_space); + z3 = (0.25 staff_space, -0.30 staff_space); + z4 = (0.50 staff_space, +0.00 staff_space); + z5 = (0.30 staff_space, +0.30 staff_space); + z6 = (0.00 staff_space, +0.15 staff_space); + + pat := z3 + .. z4 + .. z5; + + save t; + numeric t[]; + + % we have to find the envelope intersections (if any) + t1 = find_envelope_cusp (reverse ellipse, pat, 1/256) + 3; + if t1 < 3: + t1 := 3; + fi; + t2 = find_envelope_cusp (ellipse, reverse pat, 1/256); + if t2 < 0: + t2 := 3; + else: + t2 := length pat - t2 + 3; + fi; + + save dirs, s; + pair dirs[]; + + s := 1/8; + + % we approximate `draw pat' + for i = 3 step s until 5: + dirs[i] := direction (i - 3) of pat; + endfor; + + fill get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, z3 - z2, z2) + -- get_subpoint (ellipse, z3 - z2, z3) + for i = 3 step s until 5: + .. get_subpoint (ellipse, dirs[i], + point (i - 3) of pat) + endfor + .. get_subpoint (ellipse, z6 - z5, z5) + -- get_subpoint (ellipse, z6 - z5, z6) + -- get_subpoint (ellipse, z5 - z6, z6) + -- get_subpoint (ellipse, z5 - z6, z5) + -- get_subpoint (ellipse, -dirs[5], z5) + for i = (5 - s) step -s until t2: + .. get_subpoint (ellipse, -dirs[i], + point (i - 3) of pat) + endfor + .. get_subpoint (ellipse, -direction (t2 - 3) of pat, + point (t2 - 3) of pat) + -- get_subpoint (ellipse, -direction (t1 - 3) of pat, + point (t1 - 3) of pat) + for i = (floor ((t1 - 3) / s) * s + 3) step -s until (3 + s): + .. get_subpoint (ellipse, -dirs[i], + point (i - 3) of pat) + endfor + .. get_subpoint (ellipse, -dirs[3], z3) + -- get_subpoint (ellipse, z2 - z3, z3) + -- get_subpoint (ellipse, z2 - z3, z2) + -- get_subpoint (ellipse, up, z2) + -- cycle; + +% draw z1 +% -- z2 +% -- pat +% -- z6; + + set_char_box (0.00 staff_space# + 1.0 stemthick#, + 0.50 staff_space# + 1.0 stemthick#, + 0.30 staff_space# + 0.5 stemthick#, + 1.80 staff_space# + 0.5 stemthick#); + + labels (1, 2, 3, 4, 5, 6); +fet_endchar; + + +fet_endgroup ("accidentals"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-clefs.mf b/muse2/share/scoreglyphs/feta-original/parmesan-clefs.mf new file mode 100644 index 00000000..afd5058e --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-clefs.mf @@ -0,0 +1,1693 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-clefs.mf -- implement ancient clefs +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("clefs"); + +% +% character aligment: +% +% Each clef is associated with a particular pitch: the treble clef +% with the `g', the alto clef with the `c', the bass clef with the +% `f', etc. The shape of each clef character defines a vertical +% position that is assumed to represent this pitch. For the treble +% clef, it is the vertical position of the center of the spiral +% ending that represents the `g' pitch. For the bass clef, it is +% the center between the two fat dots that define the vertical +% position of the `f' pitch. For the alto clef, it is the vertical +% center of the clef that is aligned with the `c' pitch. For each +% clef character, this center should be vertically aligned with the +% point (0, 0). The horizontal alignment of each clef character +% should be such that the vertical line through the point (0, 0) +% touches the left-most edge of the clef. +% +% TODO: document exact_center +% +% set_char_box() conventions: +% +% * breapth: Ignored (as far as I know). Should be set to 0. +% +% * width: Should match the clef's width. +% +% * depth: Should match the bottom edge of the clef. Affects vertical +% collision handling. +% +% * height: Should match the top edge of the clef. Affects vertical +% collision handling. +% + + +%%%%%%%% +% +% +% +% Editio Vaticana +% +% +% +def draw_vaticana_do_clef (expr exact_center, reduction) = + save reduced_il; + + reduced_il# = staff_space# * reduction; + + set_char_box (0 - xpart exact_center, + 0.5 reduced_il# + xpart exact_center, + 0.8 reduced_il# - ypart exact_center, + 0.8 reduced_il# + ypart exact_center); + + define_pixels (reduced_il); + + save pat, ellipse, clef, T; + path pat, ellipse, clef; + transform T; + + T := identity xscaled 0.6 linethickness + yscaled 0.6 reduced_il; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + rt z11 = (xoffs + 0.50 reduced_il, yoffs - .45 reduced_il); + z12 = (xoffs + 0.25 reduced_il, yoffs - .50 reduced_il); + lft z13 = (xoffs + 0.00 reduced_il, yoffs - .28 reduced_il); + lft z14 = (xoffs, yoffs); + + pat := z11 + .. z12 + .. z13 + -- z14; + + save shift; + pair shift; + + % adjust vertically to fit into bounding box + shift = find_tangent_shift (((0, -d + 0.3 reduced_il) + -- (w, -d + 0.3 reduced_il)), pat, + (0, -d / 2), (0, d / 2)); + pat := pat shifted shift; + + clef := rt z14{down} + .. top (point 1 of pat) + .. get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, + point 0 of pat) + .. bot (point 1 of pat) + .. get_subpath (ellipse, + direction 2 of pat, up, + point 2 of pat); + + fill clef + -- reverse clef yscaled -1 + -- cycle; + + labels (11, 12, 13, 14); +enddef; + + +fet_beginchar ("Ed. Vat. do clef", "vaticana.do"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_vaticana_do_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Ed. Vat. do clef", "vaticana.do_change"); + draw_vaticana_do_clef ((0, 0), 1.0); % no reduction +fet_endchar; + + +def draw_vaticana_fa_clef (expr exact_center, reduction) = + save reduced_il, xoffs, yoffs; + + reduced_il# = staff_space# * reduction; + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (reduced_il, xoffs, yoffs); + + % left-handed punctum + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 0.6 linethickness + yscaled 0.5 reduced_il; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + lft z21 = (xoffs + 0.00 reduced_il, yoffs + 0.00 reduced_il); + z22 = (xoffs + 0.25 reduced_il, yoffs + 0.05 reduced_il); + rt z23 = (xoffs + 0.50 reduced_il, yoffs - 0.05 reduced_il); + + pat := z21 + .. z22 + .. z23; + + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z21) + .. top z22 + .. get_subpath (ellipse, + direction 2 of pat, -direction 2 of pat, z23) + .. bot z22 + .. cycle; + + % stem + pickup pencircle scaled 0.6 linethickness; + + x23 = x24; + yoffs = bot y24 + 1.5 reduced_il; + + draw_rounded_block (bot lft z24, top rt z23, 0.6 linethickness); + + labels (21, 22, 23, 24); + + % right-handed puncta as in do clef + draw_vaticana_do_clef (exact_center + (0.55 reduced_il#, 0), + reduction); + + set_char_box (0 - xpart exact_center, + 1.05 reduced_il# + xpart exact_center, + 1.5 reduced_il# - ypart exact_center, + 0.8 reduced_il# + ypart exact_center); +enddef; + + +fet_beginchar ("Ed. Vat. fa clef", "vaticana.fa"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_vaticana_fa_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Ed. Vat. fa clef", "vaticana.fa_change"); + draw_vaticana_fa_clef ((0, 0), 1.0); % no reduction +fet_endchar; + + +%%%%%%%% +% +% +% +% Editio Medicaea +% +% +% +def draw_medicaea_do_clef (expr exact_center, reduction) = + save reduced_il, reduced_slt; + + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + + define_pixels (reduced_il); + define_pixels (reduced_slt); + + set_char_box (0 - xpart exact_center, + 1.0 reduced_il# + xpart exact_center, + 1.5 reduced_il# - ypart exact_center, + 1.5 reduced_il# + ypart exact_center); + + save flag_height; + + flag_height# = 0.5 reduced_il#; + + define_pixels (flag_height); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + % flags + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled reduced_slt + yscaled flag_height; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + xoffs = lft x1 = rt x2 - reduced_il; + y1 = yoffs + 0.5 (reduced_il - flag_height - staff_space); + y2 = y1 - reduced_il + flag_height; + + fill top z1 + -- get_subpath (ellipse, z2 - z1, z1 - z2, z2) + -- bot z1 + -- cycle; + + xoffs = lft x3 = rt x4 - reduced_il; + y3 = yoffs + 0.5 (reduced_il - flag_height + staff_space); + y4 = y3 - reduced_il + flag_height; + + fill top z3 + -- get_subpath (ellipse, z4 - z3, z3 - z4, z4) + -- bot z3 + -- cycle; + + % stem + pickup pencircle scaled reduced_slt; + + lft x5 = lft x6 = xoffs; + yoffs = top y6 - 1.5 reduced_il = bot y5 + 1.5 reduced_il; + + draw_rounded_block (bot lft z5, top rt z6, reduced_slt); + + labels (1, 2, 3, 4, 5, 6); +enddef; + + +fet_beginchar ("Ed. Med. do clef", "medicaea.do"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_medicaea_do_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Ed. Med. do clef", "medicaea.do_change"); + draw_medicaea_do_clef ((0, 0), .8); +fet_endchar; + + +def draw_medicaea_fa_clef (expr exact_center, reduction) = + % inspired by Regensburger Edition of Medicaea (1885/86), in: + % MGG, volume 2, col. 1327 ("Choralreform"), fig. 2. + + save reduced_il, reduced_slt; + + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + + define_pixels (reduced_il); + define_pixels (reduced_slt); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + % stem + pickup pencircle scaled reduced_slt; + + x11 = x12 = xoffs + 0.4 reduced_il; + y11 = yoffs = bot y12 + 1.5 reduced_il; + + draw_rounded_block (bot lft z12, top rt z11, reduced_slt); + + % left-handed punctum + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled reduced_slt + yscaled reduced_il; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + lft z13 = (xoffs, yoffs); + rt z14 = z11 + (reduced_slt / 2, 0); + + fill get_subpath (ellipse, left, right, z13) + -- get_subpath (ellipse, right, left, z14) + -- cycle; + + labels (11, 12, 13, 14); + + % right-handed puncta as in do clef + draw_medicaea_do_clef (exact_center + (0.7 reduced_il#, 0), + reduction); + + set_char_box (0 - xpart exact_center, + 1.7 reduced_il# + xpart exact_center, + 1.5 reduced_il# - ypart exact_center, + 1.5 reduced_il# + ypart exact_center); +enddef; + + +fet_beginchar ("Ed. Med. fa clef", "medicaea.fa"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_medicaea_fa_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Ed. Med. fa clef", "medicaea.fa_change"); + draw_medicaea_fa_clef ((0, 0), .8); +fet_endchar; + + +%%%%%%%% +% +% +% +% Mensural Notation +% +% +% + +% +% width: interval from left end to right end +% height: interval from bottom of lower beam to top of upper beam +% exact_center: the coordinates of the vertical center point of the +% left edge. +% +def draw_brevis (expr exact_center, bwidth, bheight, blinethickness) = + save brevis_width, brevis_height, linethickness; + + brevis_width# = bwidth; + brevis_height# = bheight; + linethickness# = blinethickness; + + save beam_width, beam_height; + save serif_size, serif_protrude, hole_height; + + beam_width# = 1.4 linethickness#; + hole_height# = 3 linethickness#; + 2 beam_height# + hole_height# = brevis_height#; + serif_size# = (hole_height# - linethickness#) / 2; + serif_protrude# = 1.5 serif_size#; + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + define_pixels (brevis_width, brevis_height, linethickness); + define_pixels (beam_width, beam_height, serif_size, serif_protrude); + + z1l = (xoffs, yoffs - linethickness); + z2r = z1r + serif_size * (1, -1); + z3l = z2l + (-serif_size, -serif_protrude); + + penpos1 (beam_width, 0); + penpos2 (beam_height, 90); + penpos3 (beam_width, 180); + + save pat_in, pat_out; + path pat_in, pat_out; + + pat_out := z3r{down} + .. z3l{up} + .. z2l{right}; + pat_out := pat_out + -- reverse pat_out xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_out := pat_out + -- reverse pat_out yscaled -1 + shifted (0, 2 yoffs) + -- cycle; + + pat_in := z1r{down} + .. z2r{right}; + pat_in := pat_in + -- reverse pat_in xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_in := pat_in + -- reverse pat_in yscaled -1 + shifted (0, 2 yoffs) + -- cycle; + + fill pat_out; + unfill pat_in; + + penlabels (1, 2, 3); +enddef; + +% +% Draw two brevis notes; the second one shifted down by `shift'. +% The other parameters are the same as with `draw_brevis'. +% +def draw_double_brevis (expr exact_center, bwidth, bheight, + blinethickness, shift) = + save brevis_width, brevis_height, linethickness; + + brevis_width# = bwidth; + brevis_height# = bheight; + linethickness# = blinethickness; + + save beam_width, beam_height; + save serif_size, serif_protrude, hole_height; + + beam_width# = 1.4 linethickness#; + hole_height# = 3 linethickness#; + 2 beam_height# + hole_height# = brevis_height#; + serif_size# = (hole_height# - linethickness#) / 2; + serif_protrude# = 1.5 serif_size#; + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + define_pixels (brevis_width, brevis_height, linethickness); + define_pixels (beam_width, beam_height, serif_size, serif_protrude); + + z1l = (xoffs, yoffs - linethickness); + z2r = z1r + serif_size * (1, -1); + z3l = z2l + (-serif_size, -serif_protrude); + + penpos1 (beam_width, 0); + penpos2 (beam_height, 90); + penpos3 (beam_width, 180); + + z4 = z1 shifted (0, -shift); + z5 = z2 shifted (0, -shift); + z6 = z3 shifted (0, -shift); + + penpos4 (beam_width, 0); + penpos5 (beam_height, 90); + penpos6 (beam_width, 180); + + save pat_in, pat_out; + path pat_in, pat_out; + + pat_out := z6r{down} + .. z6l{up} + .. z5l{right}; + pat_out := pat_out + -- reverse pat_out xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_out := pat_out + -- reverse pat_out yscaled -1 + shifted (0, shift - 2 yoffs) + -- cycle; + + fill pat_out; + + pat_in := z1r{down} + .. z2r{right}; + pat_in := pat_in + -- reverse pat_in xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_in := pat_in + -- reverse pat_in yscaled -1 + shifted (0, 2 yoffs) + -- cycle; + + unfill pat_in; + unfill pat_in shifted (0, -shift); + + penlabels (1, 2, 3, 4, 5, 6); +enddef; + + +% +% Draw three brevis notes; the second one shifted down by `shift', +% the third one by `2 shift'. +% The other parameters are the same as with `draw_brevis'. +% +def draw_triple_brevis (expr exact_center, bwidth, bheight, + blinethickness, shift) = + save brevis_width, brevis_height, linethickness; + + brevis_width# = bwidth; + brevis_height# = bheight; + linethickness# = blinethickness; + + save beam_width, beam_height; + save serif_size, serif_protrude, hole_height; + + beam_width# = 1.4 linethickness#; + hole_height# = 3 linethickness#; + 2 beam_height# + hole_height# = brevis_height#; + serif_size# = (hole_height# - linethickness#) / 2; + serif_protrude# = 1.5 serif_size#; + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + define_pixels (brevis_width, brevis_height, linethickness); + define_pixels (beam_width, beam_height, serif_size, serif_protrude); + + z1l = (xoffs, yoffs - linethickness); + z2r = z1r + serif_size * (1, -1); + z3l = z2l + (-serif_size, -serif_protrude); + + penpos1 (beam_width, 0); + penpos2 (beam_height, 90); + penpos3 (beam_width, 180); + + z7 = z1 shifted (0, -2 shift); + z8 = z2 shifted (0, -2 shift); + z9 = z3 shifted (0, -2 shift); + + penpos7 (beam_width, 0); + penpos8 (beam_height, 90); + penpos9 (beam_width, 180); + + save pat_in, pat_out; + path pat_in, pat_out; + + pat_out := z9r{down} + .. z9l{up} + .. z8l{right}; + pat_out := pat_out + -- reverse pat_out xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_out := pat_out + -- reverse pat_out yscaled -1 + shifted (0, -2 yoffs) + -- cycle; + + fill pat_out; + + pat_in := z1r{down} + .. z2r{right}; + pat_in := pat_in + -- reverse pat_in xscaled -1 + shifted (2 xoffs + brevis_width, 0); + pat_in := pat_in + -- reverse pat_in yscaled -1 + shifted (0, 2 yoffs) + -- cycle; + + unfill pat_in; + unfill pat_in shifted (0, -shift); + unfill pat_in shifted (0, -2 shift); + + penlabels (1, 2, 3, 7, 8, 9); +enddef; + + +def draw_neomensural_c_clef (expr exact_center, reduction) = + save reduced_il, reduced_slt, stem_width; + + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + stem_width# = 1.4 reduced_slt#; + + define_pixels (reduced_il, reduced_slt, stem_width); + + set_char_box (0 - xpart exact_center, + 2 reduced_il# + 6 reduced_slt# + xpart exact_center, + 2 reduced_il# - ypart exact_center, + 2 reduced_il# + ypart exact_center); + + draw_brevis (exact_center + (3 reduced_slt#, 0), + 2 reduced_il#, reduced_il#, reduced_slt#); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled stem_width + yscaled blot_diameter; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft x11 = lft x12 = xoffs; + top y12 - bot y11 = 4 reduced_il; + top y12 + bot y11 = 2 yoffs; + x13 = x3; + y13 = y11; + rt x14 = rt x15 = w; + y14 = y11; + y15 = y12; + + pat := get_subpath (ellipse, down, up, z13) + -- z3l + -- z3r + -- cycle; + + fill get_subpath (ellipse, down, up, z11) + -- get_subpath (ellipse, up, down, z12) + -- cycle; + fill get_subpath (ellipse, down, up, z14) + -- get_subpath (ellipse, up, down, z15) + -- cycle; + + fill pat; + fill pat xscaled -1 + shifted (w, 0); + fill pat yscaled -1 + shifted (0, 2 yoffs); + fill pat scaled -1 + shifted (w, 2 yoffs); + + labels (11, 12, 13, 14, 15); +enddef; + + +fet_beginchar ("neo-mensural c clef", "neomensural.c"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_neomensural_c_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("neo-mensural c clef", "neomensural.c_change"); + draw_neomensural_c_clef ((0, 0), .8); +fet_endchar; + + +def draw_petrucci_c_clef (expr exact_center, flare_align, reduction) = + % inspired by Josquin Desprez, "Stabat Mater", Libro tertio, + % 1519, printed by Petrucci, in: MGG, volume 7, Table 11. + % Also by Petrucci's Canti C, Venedig 1503. In: MGG, volume + % 9, p. 1681/1682. + + save reduced_il, reduced_slt; + + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + + define_pixels (reduced_il); + + draw_double_brevis (exact_center + (0, 0.5 staff_space#), + reduced_il#, reduced_il#, reduced_slt#, + staff_space); + + save half_reduced_il, left_depth, left_height; + + half_reduced_il# = staff_space# * sqrt (reduction); + left_height# = half_reduced_il# * min (3.2, 3.2 + 0.2 + flare_align); + left_depth# = half_reduced_il# * min (3.2, 3.2 + 0.2 - flare_align); + + define_pixels (half_reduced_il); + define_pixels (left_depth, left_height); + + set_char_box (0 - xpart exact_center, + reduced_il# + xpart exact_center, + left_depth# - ypart exact_center, + left_height# + ypart exact_center); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled 1.4 linethickness + yscaled blot_diameter; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft x11 = lft x13 = xoffs; + top y11 = yoffs + left_height; + bot y13 = yoffs - left_depth; + rt x15 = rt x17 = xoffs + brevis_width; + y15 = min (y11 - 0.2 half_reduced_il, yoffs + 2.2 half_reduced_il); + y17 = max (y13 + 0.2 half_reduced_il, yoffs - 2.2 half_reduced_il); + + z12 = z14 yscaled -1; + z14 = z6; + z16 = z18 yscaled -1; + rt z18 = lft z14 shifted (brevis_width, 0); + + penpos12 (1.4 linethickness, 0); + penpos14 (1.4 linethickness, 0); + penpos16 (1.4 linethickness, 0); + penpos18 (1.4 linethickness, 0); + + if top y11 > -y6 + 0.7 linethickness: + fill get_subpath (ellipse, up, down, z11) + -- z12l + -- z12r + -- cycle; + fi; + if bot y13 < y6 - 0.7 linethickness: + fill get_subpath (ellipse, down, up, z13) + -- z14r + -- z14l + -- cycle; + fi; + if top y15 > -y6 + 0.7 linethickness: + fill get_subpath (ellipse, up, down, z15) + -- z16l + -- z16r + -- cycle; + fi; + if bot y17 < y6 - 0.7 linethickness: + fill get_subpath (ellipse, down, up, z17) + -- z18r + -- z18l + -- cycle; + fi; + + labels (11, 13, 15, 17); + penlabels (12, 14, 16, 18); +enddef; + + +fet_beginchar ("petrucci c1 clef", "petrucci.c1"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_c_clef ((0, 0), +2, 1.0); +fet_endchar; + + +fet_beginchar ("petrucci c1 clef", "petrucci.c1_change"); + draw_petrucci_c_clef ((0, 0), +2, .8); +fet_endchar; + + +fet_beginchar ("petrucci c2 clef", "petrucci.c2"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_c_clef ((0, 0), +1, 1.0); +fet_endchar; + + +fet_beginchar ("petrucci c2 clef", "petrucci.c2_change"); + draw_petrucci_c_clef ((0, 0), +1, .8); +fet_endchar; + + +fet_beginchar ("petrucci c3 clef", "petrucci.c3"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_c_clef ((0, 0), 0, 1.0); +fet_endchar; + + +fet_beginchar ("petrucci c3 clef", "petrucci.c3_change"); + draw_petrucci_c_clef ((0, 0), 0, .8); +fet_endchar; + + +fet_beginchar ("petrucci c4 clef", "petrucci.c4"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_c_clef ((0, 0), -1, 1.0); +fet_endchar; + + +fet_beginchar ("petrucci c4 clef", "petrucci.c4_change"); + draw_petrucci_c_clef ((0, 0), -1, .8); +fet_endchar; + + +fet_beginchar ("petrucci c5 clef", "petrucci.c5"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_c_clef ((0, 0), -2, 1.0); +fet_endchar; + + +fet_beginchar ("petrucci c5 clef", "petrucci.c5_change"); + draw_petrucci_c_clef ((0, 0), -2, .8); +fet_endchar; + + +def draw_mensural_c_clef (expr exact_center, reduction) = + % inspired by Ockeghem, "Missa Prolationum", in: MGG, volume + % 9, table 94. + + save reduced_il; + + reduced_il# = staff_space# * reduction; + + define_pixels (reduced_il); + + draw_triple_brevis (exact_center + (0, 0.5 staff_space#), + 2 reduced_il#, 0.8 staff_space#, + 0.8 linethickness#, staff_space); + + save half_reduced_il; + + half_reduced_il# = staff_space# * sqrt (reduction); + + define_pixels (half_reduced_il); + + set_char_box (0 - xpart exact_center, + 2 reduced_il# + xpart exact_center, + 2.2 half_reduced_il# + staff_space# - + 2 ypart exact_center, + 2.2 half_reduced_il# + 2 ypart exact_center); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled 1.4 linethickness + yscaled blot_diameter; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft x11 = lft x13 = xoffs; + top y11 = yoffs + 2.2 half_reduced_il; + bot y13 = yoffs - 2.2 half_reduced_il - staff_space; + rt x15 = rt x17 = xoffs + brevis_width; + y15 = yoffs + 1.4 half_reduced_il; + y17 = yoffs - 1.4 half_reduced_il - staff_space; + + z12 = z14 yscaled -1 shifted (0, -staff_space); + z14 = z9; + z16 = z18 yscaled -1 shifted (0, -staff_space); + rt z18 = lft z14 shifted (brevis_width, 0); + + penpos12 (1.4 linethickness, 0); + penpos14 (1.4 linethickness, 0); + penpos16 (1.4 linethickness, 0); + penpos18 (1.4 linethickness, 0); + + fill get_subpath (ellipse, up, down, z11) + -- z12l + -- z12r + -- cycle; + fill get_subpath (ellipse, down, up, z13) + -- z14r + -- z14l + -- cycle; + fill get_subpath (ellipse, up, down, z15) + -- z16l + -- z16r + -- cycle; + fill get_subpath (ellipse, down, up, z17) + -- z18r + -- z18l + -- cycle; + + labels (11, 13, 15, 17); + penlabels (12, 14, 16, 18); +enddef; + + +fet_beginchar ("mensural c clef", "mensural.c"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_mensural_c_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("mensural c clef", "mensural.c_change"); + draw_mensural_c_clef ((0, 0), .8); +fet_endchar; + + +def draw_diamond (expr exact_center, reduction) = + save stem_width, reduced_nht, holeheight, beamheight; + save rh_height, rh_width; + + stem_width# = 1.4 reduced_slt#; + reduced_nht# = noteheight# * reduction; + holeheight# = 3 reduced_slt#; + beamheight# = 0.4 (reduced_nht# - holeheight#); + + rh_height# = 1.2 staff_space# * reduction; + rh_width# / rh_height# = tand (30); + + define_pixels (beamheight, stem_width); + define_pixels (rh_height, rh_width); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled beamheight + yscaled stem_width + rotated 45; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + x21 := xoffs - rh_width / 2; + y21 := yoffs; + x22 := xoffs; + y22 := yoffs + rh_height / 2; + x23 := xoffs + rh_width / 2; + y23 := yoffs; + x24 := xoffs; + y24 := yoffs - rh_height / 2; + + fill get_subpath (ellipse, z21 - z24, z22 - z21, z21) + -- get_subpath (ellipse, z22 - z21, z23 - z22, z22) + -- get_subpath (ellipse, z23 - z22, z24 - z23, z23) + -- get_subpath (ellipse, z24 - z23, z21 - z24, z24) + -- cycle; + + save l; + path l[]; + + l2122 := (directionpoint (z21 - z22) of ellipse) shifted z21 + -- (directionpoint (z21 - z22) of ellipse) shifted z22; + l2223 := (directionpoint (z22 - z23) of ellipse) shifted z22 + -- (directionpoint (z22 - z23) of ellipse) shifted z23; + l2324 := (directionpoint (z23 - z24) of ellipse) shifted z23 + -- (directionpoint (z23 - z24) of ellipse) shifted z24; + l2421 := (directionpoint (z24 - z21) of ellipse) shifted z24 + -- (directionpoint (z24 - z21) of ellipse) shifted z21; + + unfill l2122 intersectionpoint l2223 + -- l2223 intersectionpoint l2324 + -- l2324 intersectionpoint l2421 + -- l2421 intersectionpoint l2122 + -- cycle; + + labels (21, 22, 23, 24); +enddef; + + +def draw_petrucci_f_clef (expr exact_center, reduction) = + % inspired by L'homme arme super voces musicales in Misse + % Josquin, 1502, Petrucci, in: MGG, volume 7, col. 200; also + % inspired by Gaspar van Weerbeke, "Virgo Maria" (1502), in: + % MGG, volume 9, col. 653 ("Motette"), fig. 3.; also by Andr'e + % Campra, "Entr'ee des s'er'enades" (1710), in: MGG, volume 2, + % col. 1649 ("Contredanse"), fig. 2. + + save interline, reduced_il, reduced_slt; + + interline# = staff_space#; + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + + draw_brevis (exact_center, reduced_il#, reduced_il#, reduced_slt#); + draw_diamond (exact_center + + (1.6 interline# * reduction, interline# / 2), + reduction); + draw_diamond (exact_center + + (1.6 interline# * reduction, -interline# / 2), + reduction); + + define_pixels (interline, reduced_il, reduced_slt); + + save stem_width; + + stem_width# = 1.4 reduced_slt#; + + define_pixels (stem_width); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + % brevis stem + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled stem_width + yscaled blot_diameter; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + rt x8 = xoffs + reduced_il; + y8 = y3; + rt z9 = (xoffs + reduced_il, yoffs - 4 reduced_il); + + penpos8 (stem_width, 0); + + fill get_subpath (ellipse, down, up, z9) + -- z8r + -- z8l + -- cycle; + + % upper diamond's stem + z10 = (xoffs + 1.6 interline * reduction + stem_width / 2, + yoffs + interline * reduction); + top z11 = z10 + (0, 1.5 interline * reduction); + + penpos10 (stem_width, 0); + + fill get_subpath (ellipse, up, down, z11) + -- z10l + -- z10r + -- cycle; + + % lower diamond's stem + z12 = (xoffs + 1.6 interline * reduction - stem_width / 2, + yoffs - interline * reduction); + bot z13 = z12 + (0, -3.5 interline * reduction); + + penpos12 (stem_width, 0); + + fill get_subpath (ellipse, down, up, z13) + -- z12r + -- z12l + -- cycle; + + save reduced_il, rh_height, rh_width; + + reduced_il# = staff_space# * reduction; + rh_height# = 1.2 reduced_il#; + rh_width# / rh_height# = tand (30); + + set_char_box (0 - xpart exact_center, + 1.6 interline# * reduction + 0.5 rh_width# + + xpart exact_center, + 4.5 interline# * reduction - ypart exact_center, + 2.5 interline# * reduction + ypart exact_center); + + labels (9, 11, 13); + penlabels (8, 10, 12); +enddef; + + +fet_beginchar ("petrucci f clef", "petrucci.f"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_f_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("petrucci f clef", "petrucci.f_change"); + draw_petrucci_f_clef ((0, 0), .8); +fet_endchar; + + +def draw_mensural_f_clef (expr exact_center, reduction) = + % inspired by Philippe le Duc, "Dite Signori" (1590), in: MGG, + % volume 3, col. 848 ("Duc"); also by John Dowland, "The First + % Booke of Songes" (1597), in: MGG, volume 3, col. 721 + % ("Dowland"), fig. 3. + + save width, reduced_slt, stem_width, dot_diameter; + + width# = 1.2 staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + stem_width# = 1.4 reduced_slt#; + dot_diameter# = 0.1 reduction * staff_space#; + + define_pixels (width, stem_width, staff_space, dot_diameter); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled 0.2 width + yscaled stem_width + rotated 45; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + % half circle + lft z10 = (0, 0); + + save pat; + path pat; + + pat := halfcircle scaled width + rotated -90 + shifted (z10 - (xoffs, yoffs)); + + z5 = point 0 of pat; + z6 = point 1 of pat; + z7 = point 2 of pat; + z8 = point 3 of pat; + z9 = point 4 of pat; + + save dirs; + pair dirs[]; + + dirs5 := direction 0 of pat; + dirs6 := direction 1 of pat; + dirs7 := direction 2 of pat; + dirs8 := direction 3 of pat; + dirs9 := direction 4 of pat; + + % we approximate `draw pat' + fill get_subpath (ellipse, -dirs5, dirs5, z5) + .. get_subpoint (ellipse, dirs6, z6) + .. get_subpoint (ellipse, dirs7, z7) + .. get_subpoint (ellipse, dirs8, z8) + .. get_subpath (ellipse, dirs9, -dirs9, z9) + .. get_subpoint (ellipse, -dirs8, z8) + .. get_subpoint (ellipse, -dirs7, z7) + .. get_subpoint (ellipse, -dirs6, z6) + .. cycle; + + % upper dot + rt x2 = xoffs + width; + top y1 = yoffs + 0.5 width; + z2 - z1 = (dot_diameter, -dot_diameter); + + fill get_subpath (ellipse, z1 - z2, z2 - z1, z1) + -- get_subpath (ellipse, z2 - z1, z1 - z2, z2) + -- cycle; + + % lower dot + x3 = x1; + top y1 - bot y4 = width; + z4 - z3 = (dot_diameter, -dot_diameter); + + fill get_subpath (ellipse, z3 - z4, z4 - z3, z3) + -- get_subpath (ellipse, z4 - z3, z3 - z4, z4) + -- cycle; + + set_char_box (0 - xpart exact_center, + width# + xpart exact_center, + 0.5 width# - ypart exact_center, + 0.5 width# + ypart exact_center); + + labels (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +enddef; + + +fet_beginchar ("mensural f clef", "mensural.f"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_mensural_f_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("mensural f clef", "mensural.f_change"); + draw_mensural_f_clef ((0, 0), .8); +fet_endchar; + + +def draw_petrucci_g_clef (expr exact_center, reduction) = + % inspired by Josquin Desprez, "Stabat Mater", Libro tertio, + % 1519, printed by Petrucci, in: MGG, volume 7, Table 11. + + save reduced_il, reduced_slt; + + reduced_il# = staff_space# * reduction; + reduced_slt# = linethickness# * reduction; + define_pixels (reduced_il, reduced_slt); + + set_char_box (0 - xpart exact_center, + 1.25 reduced_il# + xpart exact_center, + 0.65 reduced_il# - ypart exact_center, + 3.80 reduced_il# + ypart exact_center); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, paths, sub_path, outlines, sub_outlines, T; + path ellipse, paths[], sub_path, outlines[], sub_outlines[]; + transform T; + + T := identity xscaled 0.5 reduced_slt + yscaled 0.22 reduced_il + rotated -35; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft z1 = (xoffs + 0.80 reduced_il, yoffs + 0.00 reduced_il); + lft z2 = (xoffs + 1.00 reduced_il, yoffs + 1.20 reduced_il); + lft z3 = (xoffs + 0.70 reduced_il, yoffs + 2.00 reduced_il); + lft z4 = (xoffs + 0.30 reduced_il, yoffs + 3.00 reduced_il); + lft z5 = (xoffs + 0.80 reduced_il, yoffs + 3.70 reduced_il); + lft z6 = (xoffs + 1.00 reduced_il, yoffs + 3.00 reduced_il); + lft z7 = (xoffs + 0.60 reduced_il, yoffs + 2.00 reduced_il); + lft z8 = (xoffs + 0.30 reduced_il, yoffs + 1.70 reduced_il); + lft z9 = (xoffs + 0.00 reduced_il, yoffs + 0.75 reduced_il); + lft z10 = (xoffs + 0.20 reduced_il, yoffs + 0.60 reduced_il); + + paths1 := z1{-1, 2} + .. z2 + .. z3 + .. z4 + .. z5 + .. z6 + .. z7 + .. z8 + .. z9 + .. z10; + + save dirs, s; + pair dirs[]; + + s := 1/4; + + % we approximate `draw paths1' + for i = 1 step s until (length paths1 + 1): + dirs[i] := direction (i - 1) of paths1; + endfor; + + outlines1 := get_subpath (ellipse, -dirs1, dirs1, z1) + for i = (1 + s) step s until (length paths1 + 1 - s): + .. get_subpoint (ellipse, dirs[i], + point (i - 1) of paths1) + endfor + .. get_subpath (ellipse, dirs10, -dirs10, z10) + for i = (length paths1 + 1 - s) step -s until (1 + s): + .. get_subpoint (ellipse, -dirs[i], + point (i - 1) of paths1) + endfor + .. cycle; + + save len; + + len := length outlines1; + + sub_outlines1 := subpath (0, + floor (1/4 len)) of outlines1; + sub_outlines2 := subpath (floor (1/4 len), + floor (2/4 len)) of outlines1; + sub_outlines3 := subpath (floor (2/4 len), + floor (3/4 len)) of outlines1; + sub_outlines4 := subpath (floor (3/4 len), + len) of outlines1; + + save times; + numeric times[]; + + (times12, times21) = sub_outlines1 intersectiontimes sub_outlines2; + (times13, times31) = sub_outlines1 intersectiontimes sub_outlines3; + (times42, times24) = sub_outlines4 intersectiontimes sub_outlines2; + (times43, times34) = sub_outlines4 intersectiontimes sub_outlines3; + + T := identity xscaled 0.75 reduced_slt + yscaled 0.33 reduced_il + rotated -35; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft z21 = (xoffs + 1.05 reduced_il, yoffs + 0.45 reduced_il); + lft z22 = (xoffs + 0.55 reduced_il, yoffs + 0.45 reduced_il); + lft z23 = (xoffs + 0.55 reduced_il, yoffs - 0.45 reduced_il); + lft z24 = (xoffs + 1.05 reduced_il, yoffs - 0.45 reduced_il); + lft z25 = (xoffs + 1.10 reduced_il, yoffs + 0.00 reduced_il); + lft z26 = (xoffs + 0.80 reduced_il, yoffs + 0.00 reduced_il); + + paths2 := z21 + .. z22 + .. z23 + .. z24 + .. {up}z25 + -- z26; + + sub_path := subpath (0, 1) of paths2; + + times1 = xpart (sub_outlines1 intersectiontimes sub_path); + times4 = xpart (sub_outlines4 intersectiontimes sub_path); + + % we have to find the envelope intersections (if any) + save t; + numeric t[]; + + t1 = find_envelope_cusp (reverse ellipse, + subpath (1, 2) of paths2, + 1/256) + 1; + if t1 < 1: + t1 := 1; + t2 := 1; + else: + t2 = find_envelope_cusp (ellipse, + subpath (3, 4) of reverse paths2, + 1/256) + 3; + t2 := length paths2 - t2; + fi; + + t3 = find_envelope_cusp (reverse ellipse, + subpath (2, 4 - epsilon) of paths2, + 1/256) + 2; + if t3 < 2: + t3 := 3; + t4 := 3; + else: + t4 = find_envelope_cusp (ellipse, + subpath (1 + epsilon, 3) + of reverse paths2, + 1/256) + 1; + t4 := length paths2 - t4; + fi; + + fill subpath (times1 + s / 4, times13) of sub_outlines1 + -- subpath (times31, infinity) of sub_outlines3 + & subpath (0, times42) of sub_outlines4 + -- subpath (times24, infinity) of sub_outlines2 + & subpath (0, times34) of sub_outlines3 + -- subpath (times43, times4 - s / 4) of sub_outlines4 + -- cycle; + unfill subpath (times12, infinity) of sub_outlines1 + & subpath (0, times21) of sub_outlines2 + -- cycle; + fill subpath (times4 + s / 4, infinity) of sub_outlines4 + & subpath (0, times1 - s / 4) of sub_outlines1 + -- cycle; + + + % we approximate `draw paths2' + for i = 1 step s until (length paths2 - s): + dirs[i + 20] := direction (i - 1) of paths2; + endfor; + + sub_outlines21 := get_subpath (ellipse, -dirs21, dirs21, z21) + for i = (1 + s) step s until (length paths2 - s): + .. get_subpoint (ellipse, dirs[i + 20], + point (i - 1) of paths2) + endfor + .. get_subpath (ellipse, up, z26 - z25, z25); + sub_outlines22 := get_subpath (ellipse, z26 - z25, z25 - z26, z26) + -- get_subpoint (ellipse, z25 - z26, z25); + sub_outlines23 := get_subpoint (ellipse, down, z25) + for i = (length paths2 - s) step -s until (t4 + 1): + .. get_subpoint (ellipse, -dirs[i + 20], + point (i - 1) of paths2) + endfor + .. get_subpoint (ellipse, -direction t4 of paths2, + point t4 of paths2); + sub_outlines24 := get_subpoint (ellipse, -direction t3 of paths2, + point t3 of paths2) + for i = (floor (t3 / s) * s + 1) step -s until (t2 + 1): + .. get_subpoint (ellipse, -dirs[i + 20], + point (i - 1) of paths2) + endfor + .. get_subpoint (ellipse, -direction t2 of paths2, + point t2 of paths2); + sub_outlines25 := get_subpoint (ellipse, -direction t1 of paths2, + point t1 of paths2) + for i = (floor (t1 / s) * s + 1) step -s until (1 + s): + .. get_subpoint (ellipse, -dirs[i + 20], + point (i - 1) of paths2) + endfor; + + (times2223, times2322) = sub_outlines22 intersectiontimes sub_outlines23; + (times2324, times2423) = sub_outlines23 intersectiontimes sub_outlines24; + (times2425, times2524) = sub_outlines24 intersectiontimes sub_outlines25; + + fill sub_outlines21 + -- subpath (0, times2223) of sub_outlines22 + -- subpath (times2322, times2324) of sub_outlines23 + -- subpath (times2423, times2425) of sub_outlines24 + -- subpath (times2524, infinity) of sub_outlines25 + .. cycle; + + labels (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + labels (21, 22, 23, 24, 25, 26); +enddef; + + +fet_beginchar ("petrucci g clef", "petrucci.g"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_g_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("petrucci g clef", "petrucci.g_change"); + draw_petrucci_g_clef ((0, 0), .8); +fet_endchar; + + +def draw_mensural_g_clef (expr exact_center, reduction) = + % TODO: Rewrite me. The former mensural g clef looked ugly, and the + % code was removed when it broke for small font sizes after some + % global changes in the font. Currently, the character is mapped to + % a copy of the petrucci g clef (which, after all, *is* a mensural g + % clef, but not the one that we have in mind here). -- jr + % + % Possible sources of inspiration for this clef include: Francisco + % Guerrero, "Lib. 1. Missarum" (1566), in: MGG, volume 3, col. 858 + % ("Ducis"); Stefano Fabri, "Quam speciosa veteranis" (1611), in: + % MGG, volume 3, col. 1698 ("Fabri"); Philippus Dulichius, + % "Fasciculus novus ..." (1598), in: MGG, volume 3, col. 919 + % ("Dulichius"), fig. 1; Noe Faignient, "Ic sal de Heer myn God + % gebenedye" (1568), in: MGG, volume 3, col. 1735 ("Faignient"). +enddef; + + +% +% FIXME: This clef is preliminarily mapped to the petrucci g clef +% until the code for the mensural g clef will be rewritten. +% +fet_beginchar ("mensural g clef", "mensural.g"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_petrucci_g_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("mensural g clef", "mensural.g_change"); + draw_petrucci_g_clef ((0, 0), .8); +fet_endchar; + + + +%%%%%%%% +% +% +% +% Hufnagel +% +% +% +def draw_hufnagel_do_clef (expr exact_center, reduction) = + % inspired by Graduale of Friedrich Zollner (1442), in: MGG, + % volume 9, col. 1413 ("Neustift"), fig. 1. + + save reduced_il; + + reduced_il# = staff_space# * reduction; + + define_pixels (reduced_il); + + set_char_box (0 - xpart exact_center, + 1.10 reduced_il# + xpart exact_center, + 0.70 reduced_il# - ypart exact_center, + 0.75 reduced_il# + ypart exact_center); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 0.6 reduced_il + yscaled 0.1 reduced_il + rotated 40; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z1 = (xoffs + 0.90 reduced_il, yoffs + .45 reduced_il); + z2 = (xoffs + 0.80 reduced_il, yoffs + .45 reduced_il); + z3 = (xoffs + 0.50 reduced_il, yoffs + .60 reduced_il); + z4 = (xoffs + 0.20 reduced_il, yoffs + .45 reduced_il); + z5 = (xoffs + 0.20 reduced_il, yoffs - .45 reduced_il); + z6 = (xoffs + 0.40 reduced_il, yoffs - .55 reduced_il); + + pat := z1 + .. z2 + .. z3 + -- z4 + -- z5 + -- z6; + + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z1) + .. get_subpoint (ellipse, direction 1 of pat, z2) + .. get_subpath (ellipse, + direction (2 - epsilon) of pat, z4 - z3, z3) + -- get_subpath (ellipse, + z4 - z3, z5 - z4, z4) + -- get_subpath (ellipse, + z5 - z4, z6 - z5, z5) + -- get_subpath (ellipse, + z6 - z5, z5 - z6, z6) + -- get_subpoint (ellipse, z5 - z6, z5) + -- get_subpoint (ellipse, z4 - z5, z5) + -- get_subpoint (ellipse, z4 - z5, z4) + -- get_subpoint (ellipse, -direction (2 - epsilon) of pat, z3) + .. get_subpath (ellipse, + -direction 1 of pat, -direction 1 of pat, z2) + .. cycle; + + labels (1, 2, 3, 4, 5, 6); +enddef; + + +fet_beginchar ("Hufnagel do clef", "hufnagel.do"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_hufnagel_do_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Hufnagel do clef", "hufnagel.do_change"); + draw_hufnagel_do_clef ((0, 0), .8); +fet_endchar; + + +def draw_hufnagel_fa_clef (expr exact_center, reduction) = + % inspired by Bamberger Manuscript (15th century), in: + % MGG, volume 2, table 59. + + save reduced_il; + + reduced_il# = staff_space# * reduction; + + define_pixels (reduced_il); + + set_char_box (0 - xpart exact_center, + 1.20 reduced_il# + xpart exact_center, + 1.15 reduced_il# - ypart exact_center, + 1.00 reduced_il# + ypart exact_center); + + save xoffs, yoffs; + + xoffs# = xpart exact_center; + yoffs# = ypart exact_center; + + define_pixels (xoffs, yoffs); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 0.6 reduced_il + yscaled 0.1 reduced_il + rotated 40; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z11 = (xoffs + 0.90 reduced_il, yoffs + 0.70 reduced_il); + z12 = (xoffs + 0.80 reduced_il, yoffs + 0.70 reduced_il); + z13 = (xoffs + 0.50 reduced_il, yoffs + 0.85 reduced_il); + z14 = (xoffs + 0.20 reduced_il, yoffs + 0.70 reduced_il); + z15 = (xoffs + 0.20 reduced_il, yoffs - 1.10 reduced_il); + + pat := z11 + .. z12 + .. z13 + -- z14 + -- z15; + + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z11) + .. get_subpoint (ellipse, direction 1 of pat, z12) + .. get_subpath (ellipse, + direction (2 - epsilon) of pat, z14 - z13, z13) + -- get_subpath (ellipse, + z14 - z13, z15 - z14, z14) + -- get_subpath (ellipse, + z15 - z14, z14 - z15, z15) + -- get_subpoint (ellipse, z14 - z15, z14) + -- get_subpoint (ellipse, -direction (2 - epsilon) of pat, z13) + .. get_subpath (ellipse, + -direction 1 of pat, -direction 1 of pat, z12) + .. cycle; + + z16 = (xoffs + 0.90 reduced_il, yoffs - 0.05 reduced_il); + z17 = (xoffs + 0.80 reduced_il, yoffs - 0.05 reduced_il); + z18 = (xoffs + 0.50 reduced_il, yoffs + 0.10 reduced_il); + z19 = (xoffs + 0.20 reduced_il, yoffs - 0.05 reduced_il); + + pat := z16 + .. z17 + .. z18 + -- z19; + + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z16) + .. get_subpoint (ellipse, direction 1 of pat, z17) + .. get_subpath (ellipse, + direction (2 - epsilon) of pat, z19 - z18, z18) + -- get_subpoint (ellipse, z19 - z18, z19) + -- get_subpoint (ellipse, -direction (2 - epsilon) of pat, z18) + .. get_subpoint (ellipse, -direction 1 of pat, z17) + .. cycle; + + labels (11, 12, 13, 14, 15, 16, 17, 18, 19); +enddef; + + +fet_beginchar ("Hufnagel fa clef", "hufnagel.fa"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_hufnagel_fa_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Hufnagel fa clef", "hufnagel.fa_change"); + draw_hufnagel_fa_clef ((0, 0), .8); +fet_endchar; + + +def draw_hufnagel_do_fa_clef (expr exact_center, reduction) = + draw_hufnagel_do_clef (exact_center, reduction); + draw_hufnagel_fa_clef (exact_center + (0, -2 staff_space#), reduction); + + set_char_box (0 - xpart exact_center, + 1.20 reduced_il# + xpart exact_center, + 1.15 reduced_il# + 2 staff_space# - ypart exact_center, + 0.75 reduced_il# + ypart exact_center); +enddef; + + +fet_beginchar ("Hufnagel do/fa clef", "hufnagel.do.fa"); + if test = 1: + draw_staff (-1, 3, 0.0); + fi; + draw_hufnagel_do_fa_clef ((0, 0), 1.0); +fet_endchar; + + +fet_beginchar ("Hufnagel do/fa clef", "hufnagel.do.fa_change"); + draw_hufnagel_do_fa_clef ((0, 0), .8); +fet_endchar; + + +fet_endgroup ("clefs"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-custodes.mf b/muse2/share/scoreglyphs/feta-original/parmesan-custodes.mf new file mode 100644 index 00000000..d1a2d6c7 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-custodes.mf @@ -0,0 +1,500 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-custodes.mf -- implement ancient custodes +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2000--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +save black_notehead_width; +numeric black_notehead_width; + +fet_begingroup ("custodes"); + +% +% character aligment: +% +% The custos is assumed to be vertically centered around (0, 0). +% The left-most edge of the custos should touch the vertical line +% that goes though the point (0, 0). +% +% set_char_box() conventions: +% +% * breapth: Ignored (as far as I know). Should be set to 0. +% +% * width: Should cover the horizontal range of the custos that is to +% be printed in the staff. If the custos has an appendage that is +% supposed to reach beyond the right end of the staff, the width +% should be set such that the appendage is outside of the char box. +% +% * depth: Should match the bottom edge of the custos. Affects +% vertical collision handling. +% +% * height: Should match the top edge of the custos. Affects vertical +% collision handling. +% + +save between_staff_lines, on_staff_line, anywhere; + +between_staff_lines := 0; +on_staff_line := 1; +anywhere := 2; + +save dir_up, dir_down; + +dir_up := 1; +dir_down := -1; + + +%%%%%%%% +% +% +% Hufnagel style +% +% + +% parameterized hufnagel custos +def custos_hufnagel (expr verbose_name, internal_name, + direction, staffline_adjustment) = + + fet_beginchar (verbose_name, internal_name); + save alpha, dalpha, ht, wd, stem_ht, pen_size; + + ht# = noteheight#; + wd# / ht# = 0.6; + alpha = 35; + dalpha = direction * alpha; + + if staffline_adjustment = between_staff_lines: + stem_ht# = 1.00 staff_space#; + elseif staffline_adjustment = on_staff_line: + stem_ht# = 1.50 staff_space#; + else: % staffline_adjustment = anywhere + stem_ht# = 1.25 staff_space#; + fi; + + pen_size# = 0.5 (wd# ++ ht#); + + define_pixels (ht, wd, pen_size, stem_ht); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled linethickness + yscaled pen_size + rotated -dalpha; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + if direction = dir_up: + top y1 = ht / 2; + bot y2 = -ht / 2; + else: + bot y1 = -ht / 2; + top y2 = ht / 2; + fi; + + lft x1 = 0; + rt x2 = wd; + y3 - y2 = direction * stem_ht; + (y3 - y2) = (x3 - x2) * tand (90 - dalpha); + + fill get_subpath (ellipse, z1 - z2, z2 - z1, z1) + if direction > 0: + -- get_subpath (ellipse, z2 - z1, z3 - z2, z2) + else: + -- get_subpoint (ellipse, z2 - z1, z2) + -- get_subpoint (ellipse, z3 - z2, z2) + fi + -- get_subpath (ellipse, z3 - z2, z2 - z3, z3) + if direction > 0: + -- get_subpoint (ellipse, z2 - z3, z2) + -- get_subpoint (ellipse, z1 - z2, z2) + else: + -- get_subpath (ellipse, z2 - z3, z1 - z2, z2) + fi + -- cycle; + + % The stem is intentionally outside of the char box. + if direction > 0: + set_char_box (0, wd#, ht# / 2, stem_ht#); + else: + set_char_box (0, wd#, stem_ht#, ht# / 2); + fi; + + labels (1, 2, 3); + fet_endchar; +enddef; + + +% custos hufnagel, stem up, between staff lines +custos_hufnagel ("Custos Hufnagel", "hufnagel.u0", + dir_up, between_staff_lines); + + +% custos hufnagel, stem up, on staff line +custos_hufnagel ("Custos Hufnagel", "hufnagel.u1", + dir_up, on_staff_line); + + +% custos hufnagel, stem up, anywhere +custos_hufnagel ("Custos Hufnagel", "hufnagel.u2", + dir_up, anywhere); + + +% custos hufnagel, stem down, between staff lines +custos_hufnagel ("Reverse Custos Hufnagel", "hufnagel.d0", + dir_down, between_staff_lines); + + +% custos hufnagel, stem down, on staff line +custos_hufnagel ("Reverse Custos Hufnagel", "hufnagel.d1", + dir_down, on_staff_line); + + +% custos hufnagel, stem down, anywhere +custos_hufnagel ("Reverse Custos Hufnagel", "hufnagel.d2", + dir_down, anywhere); + + +%%%%%%%% +% +% +% Medicaea style +% +% + +def custos_medicaea (expr verbose_name, internal_name, + direction, staffline_adjustment) = + fet_beginchar (verbose_name, internal_name); + save ht, wd, stem_ht; + + ht# = noteheight#; + wd# / ht# = 0.25; + + if staffline_adjustment = between_staff_lines: + stem_ht# = 1.00 staff_space#; + elseif staffline_adjustment = on_staff_line: + stem_ht# = 1.50 staff_space#; + else: % staffline_adjustment = anywhere + stem_ht# = 1.25 staff_space#; + fi; + + define_pixels (ht, wd, stem_ht); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled 0.6 linethickness + yscaled ht; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + lft x1 = 0; + y1 = 0; + rt x2 = wd; + y2 = y1; + + fill get_subpath (ellipse, left, right, z1) + -- get_subpath (ellipse, right, left, z2) + -- cycle; + + pickup pencircle scaled 0.6 linethickness; + + rt x3 = wd; + y3 = 0; + x4 = x3; + if direction > 0: + top y4 = stem_ht; + draw_rounded_block (bot lft z3, top rt z4, + 0.6 linethickness); + else: + bot y4 = -stem_ht; + draw_rounded_block (bot lft z4, top rt z3, + 0.6 linethickness); + fi; + + + if direction > 0: + set_char_box (0, wd#, ht# / 2, stem_ht#); + else: + set_char_box (0, wd#, stem_ht#, ht# / 2); + fi; + + labels (1, 2, 3, 4); + fet_endchar; +enddef; + + +% custos medicaea, stem up, between staff lines +custos_medicaea ("Custos Med.", "medicaea.u0", + dir_up, between_staff_lines); + + +% custos medicaea, stem up, on staff line +custos_medicaea ("Custos Med.", "medicaea.u1", + dir_up, on_staff_line); + + +% custos medicaea, stem up, anywhere +custos_medicaea ("Custos Med.", "medicaea.u2", + dir_up, anywhere); + + +% custos medicaea, stem down, between staff lines +custos_medicaea ("Reverse Custos Med.", "medicaea.d0", + dir_down, between_staff_lines); + + +% custos medicaea, stem down, on staff line +custos_medicaea ("Reverse Custos Med.", "medicaea.d1", + dir_down, on_staff_line); + + +% custos medicaea, stem down, anywhere +custos_medicaea ("Reverse Custos Med.", "medicaea.d2", + dir_down, anywhere); + + +%%%%%%%% +% +% +% Editio Vaticana style +% +% + +def custos_vaticana (expr verbose_name, internal_name, + direction, staffline_adjustment) = + fet_beginchar (verbose_name, internal_name); + save ht, wd, u_offs, l_offs, stem_size, stem_end; + save pen_ht, l_shift, curve_ht, bend_ht; + + ht# = noteheight#; + wd# = 0.24 ht#; + + if staffline_adjustment = between_staff_lines: + stem_size# = 1.00; + elseif staffline_adjustment = on_staff_line: + stem_size# = 1.50; + else: % staffline_adjustment = anywhere + stem_size# = 1.25; + fi; + + curve_ht# = 0.6 ht#; + bend_ht# = 0.10 ht#; + l_shift# = 0.04 ht#; + u_offs# = +direction * 0.5 * (bend_ht# + l_shift#); + l_offs# = -direction * 0.5 * (bend_ht# - l_shift#); + stem_end# = direction * stem_size# * staff_space#; + pen_ht# = curve_ht# - l_shift#; + + define_pixels (u_offs, l_offs, stem_end, ht, wd, pen_ht); + + pickup pencircle scaled 0.6 linethickness; + + z1 = (0, u_offs); + z2 = (0.7 wd, l_offs); + z3 = (wd, l_offs); + + penpos1 (pen_ht, 90); + penpos2 (pen_ht, 90); + penpos3 (pen_ht, 90); + + penstroke z1e{z2 - z1} + .. {right}z2e + .. z3e; + + rt x4 = wd; + x5 = x4; + + if direction > 0: + y4 = y3r; + top y5 = stem_end; + draw_rounded_block (bot lft z4, top rt z5, + 0.6 linethickness); + else: + y4 = y3l; + bot y5 = stem_end; + draw_rounded_block (bot lft z5, top rt z4, + 0.6 linethickness); + fi; + + if direction > 0: + set_char_box (0, wd#, + -l_offs# + 0.5 pen_ht#, stem_end#); + else: + set_char_box (0, wd#, + -stem_end#, +l_offs# + 0.5 pen_ht#); + fi; + + penlabels (1, 2, 3); + labels (4, 5); + fet_endchar; +enddef; + + +% custos vaticana, stem up, between staff lines +custos_vaticana ("Custos Ed. Vat.", "vaticana.u0", + dir_up, between_staff_lines); + + +% custos vaticana, stem up, on staff line +custos_vaticana ("Custos Ed. Vat.", "vaticana.u1", + dir_up, on_staff_line); + + +% custos vaticana, stem up, anywhere +custos_vaticana ("Custos Ed. Vat.", "vaticana.u2", + dir_up, anywhere); + + +% custos vaticana, stem down, between staff lines +custos_vaticana ("Reverse Custos Ed. Vat.", "vaticana.d0", + dir_down, between_staff_lines); + + +% custos vaticana, stem down, on_staff_line +custos_vaticana ("Reverse Custos Ed. Vat.", "vaticana.d1", + dir_down, on_staff_line); + + +% custos vaticana, stem down, anywhere +custos_vaticana ("Reverse Custos Ed. Vat.", "vaticana.d2", + dir_down, anywhere); + + +%%%%%%%% +% +% +% Mensural style +% +% + +def custos_mensural (expr verbose_name, internal_name, + direction, staffline_adjustment) = + fet_beginchar (verbose_name, internal_name); + save alpha, dalpha, ht, wd, stem_ht; + + ht# = noteheight#; + wd# / ht# = 1.2; + alpha = 35; + dalpha = direction * alpha; + + if staffline_adjustment = between_staff_lines: + stem_ht# = 1.00 staff_space#; + elseif staffline_adjustment = on_staff_line: + stem_ht# = 1.50 staff_space#; + else: % staffline_adjustment = anywhere + stem_ht# = 1.25 staff_space#; + fi; + + define_pixels (ht, wd, stem_ht); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled linethickness + yscaled 0.4 ht + rotated -dalpha; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + if direction > 0: + bot y1 = bot y3 = bot y5 = -direction * 0.33 ht; + top y2 = top y4 = +direction * 0.33 ht; + else: + top y1 = top y3 = top y5 = -direction * 0.33 ht; + bot y2 = bot y4 = +direction * 0.33 ht; + fi; + + lft x1 = 0.0 wd; + lft x2 = 0.2 wd; + lft x3 = 0.4 wd; + lft x4 = 0.6 wd; + lft x5 = 0.8 wd; + + y6 - y5 = direction * stem_ht; + y6 - y5 = (x6 - x5) * tand (90 - dalpha); + + if direction > 0: + fill get_subpath (ellipse, z1 - z2, z2 - z1, z1) + -- get_subpoint (ellipse, z2 - z1, z2) + -- get_subpoint (ellipse, z3 - z2, z2) + -- get_subpath (ellipse, z3 - z2, z4 - z3, z3) + -- get_subpoint (ellipse, z4 - z3, z4) + -- get_subpoint (ellipse, z5 - z4, z4) + -- get_subpath (ellipse, z5 - z4, z6 - z5, z5) + -- get_subpath (ellipse, z6 - z5, z5 - z6, z6) + -- get_subpoint (ellipse, z5 - z6, z5) + -- get_subpoint (ellipse, z4 - z5, z5) + -- get_subpath (ellipse, z4 - z5, z3 - z4, z4) + -- get_subpoint (ellipse, z3 - z4, z3) + -- get_subpoint (ellipse, z2 - z3, z3) + -- get_subpath (ellipse, z2 - z3, z1 - z2, z2) + -- cycle; + else: + fill get_subpath (ellipse, z1 - z2, z2 - z1, z1) + -- get_subpath (ellipse, z2 -z1, z3 - z2, z2) + -- get_subpoint (ellipse, z3 - z2, z3) + -- get_subpoint (ellipse, z4 - z3, z3) + -- get_subpath (ellipse, z4 -z3, z5 - z4, z4) + -- get_subpoint (ellipse, z5 - z4, z5) + -- get_subpoint (ellipse, z6 - z5, z5) + -- get_subpath (ellipse, z6 - z5, z5 - z6, z6) + -- get_subpath (ellipse, z5 - z6, z4 - z5, z5) + -- get_subpoint (ellipse, z4 - z5, z4) + -- get_subpoint (ellipse, z3 - z4, z4) + -- get_subpath (ellipse, z3 - z4, z2 - z3, z3) + -- get_subpoint (ellipse, z2 - z3, z2) + -- get_subpoint (ellipse, z1 - z2, z2) + -- cycle; + fi; + + % The stem is intentionally outside of the char box. + if direction > 0: + set_char_box (0, wd#, + +direction * 0.33 ht#, stem_ht#); + else: + set_char_box (0, wd#, + stem_ht#, -direction * 0.33 ht#); + fi; + + labels (1, 2, 3, 4, 5, 6); + fet_endchar; +enddef; + + +% custos mensural, stem up, between staff lines +custos_mensural ("Custos Mensural", "mensural.u0", + dir_up, between_staff_lines); + + +% custos mensural, stem up, on staff line +custos_mensural ("Custos Mensural", "mensural.u1", + dir_up, on_staff_line); + + +% custos mensural, stem up, anywhere +custos_mensural ("Custos Mensural", "mensural.u2", + dir_up, anywhere); + + +% custos mensural, stem down, between staff lines +custos_mensural ("Reverse Custos Mensural", "mensural.d0", + dir_down, between_staff_lines); + + +% custos mensural, stem down, on staff line +custos_mensural ("Reverse Custos Mensural", "mensural.d1", + dir_down, on_staff_line); + + +% custos mensural, stem down, anywhere +custos_mensural ("Reverse Custos Mensural", "mensural.d2", + dir_down, anywhere); + + +fet_endgroup ("custodes"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-dots.mf b/muse2/share/scoreglyphs/feta-original/parmesan-dots.mf new file mode 100644 index 00000000..826dabe2 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-dots.mf @@ -0,0 +1,27 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-dots.mf -- dot vaticana +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2006--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("dots"); + +save dot_diam; + +3 dot_diam# = staff_space# - stafflinethickness#; +define_whole_blacker_pixels (dot_diam); + +fet_beginchar ("duration dot", "dotvaticana"); + pickup pencircle scaled dot_diam; + + lft x0 = 0; + top y0 = vround (.5 dot_diam); + + drawdot z0; + + set_char_box (0, dot_diam#, .5 dot_diam#, .5 dot_diam#); +fet_endchar; + +fet_endgroup ("dots"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-flags.mf b/muse2/share/scoreglyphs/feta-original/parmesan-flags.mf new file mode 100644 index 00000000..32a55df0 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-flags.mf @@ -0,0 +1,326 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-flags.mf -- implement ancient flags +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("flags"); + +save between_staff_lines, on_staff_line, anywhere; + +between_staff_lines := 0; +on_staff_line := 1; +anywhere := 2; + +save dir_up, dir_down; + +dir_up := 1; +dir_down := -1; + + +%%%%%%%% +% +% +% +% Mensural Notation +% +% +% + +def draw_mensural_outermost_flare (expr staffline_adjustment, d_) = + define_pixels (linethickness, staff_space); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 1.00 linethickness + yscaled 0.22 staff_space + rotated -35; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + z11 = (+0.00 staff_space, -0.00 staff_space); + z12 = (+0.15 staff_space, -0.00 staff_space); + + if staffline_adjustment = between_staff_lines: + z13 = (+0.45 staff_space, -0.35 staff_space); + z14 = (+0.45 staff_space, -0.85 staff_space); + z15 = (+0.00 staff_space, -2.00 staff_space); + elseif staffline_adjustment = on_staff_line: + z13 = (+0.20 staff_space, -0.05 staff_space); + z14 = (+0.20 staff_space, -1.15 staff_space); + z15 = (+0.00 staff_space, -1.40 staff_space); + else: % staffline_adjustment = anywhere + z13 = (+0.33 staff_space, -0.20 staff_space); + z14 = (+0.33 staff_space, -1.00 staff_space); + z15 = (+0.00 staff_space, -1.70 staff_space); + fi; + + pat := z13{z13 - z12} + .. {z15 - z14}z14; + + fill get_subpath (ellipse, z11 - z12, z12 - z11, z11) + -- get_subpoint (ellipse, z12 - z11, z12) + -- get_subpoint (ellipse, z13 - z12, z12) + -- get_subpoint (ellipse, direction 0 of pat, z13) + {direction 0 of pat} + .. {direction 1 of pat} + get_subpoint (ellipse, direction 1 of pat, z14) + -- get_subpath (ellipse, z15 - z14, z14 - z15, z15) + -- get_subpoint (ellipse, -direction 1 of pat, z14) + {-direction 1 of pat} + .. {-direction 0 of pat} + get_subpoint (ellipse, -direction 0 of pat, z13) + -- get_subpath (ellipse, z12 - z13, z11 - z12, z12) + -- cycle; + + if d_ = dir_up: + labels (11, 12, 13, 14, 15); + fi; +enddef; + + +def draw_mensural_inner_flare (expr il_shift, idx, d_) = + define_pixels (linethickness, staff_space); + + save ellipse, pat, T; + path ellipse, pat; + transform T; + + T := identity xscaled 1.00 linethickness + yscaled 0.22 staff_space + rotated -35; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + save i; + numeric i[]; + + i0 := idx * 10; + i1 := idx * 10 + 1; + i2 := idx * 10 + 2; + i3 := idx * 10 + 3; + i4 := idx * 10 + 4; + + z[i0] = (0, -il_shift * staff_space); + z[i1] = z[i0] + (+0.00 staff_space, -0.10 staff_space); + z[i2] = z[i0] + (+0.33 staff_space, -0.30 staff_space); + z[i3] = z[i0] + (+0.33 staff_space, -0.70 staff_space); + z[i4] = z[i0] + (+0.00 staff_space, -0.90 staff_space); + + pat := z[i1]{2, 1} + .. z[i2] + .. z[i3] + .. {-2, -1}z[i4]; + + % we avoid cusps originally present in `draw pat' + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z[i1]) + .. get_subpoint (ellipse, direction 1 of pat, z[i2]) + {direction 1 of pat} + .. get_subpoint (ellipse, direction 2 of pat, z[i3]) + {direction 2 of pat} + .. get_subpath (ellipse, + direction 3 of pat, -direction 3 of pat, z[i4]) + .. get_subpoint (ellipse, -direction 2 of pat, z[i3]) + {-direction 2 of pat} + .. get_subpoint (ellipse, -direction 1 of pat, z[i2]) + {-direction 1 of pat} + .. cycle; + + if d_ = dir_up: + labels ([i0], [i1], [i2], [i3], [i4]); + fi; +enddef; + + +def draw_mensural_flag (expr staffline_adjustment, flares, d_) = + save char_box_adjust, flare_shift; + + if staffline_adjustment = between_staff_lines: + flare_shift := 0.5; + elseif staffline_adjustment = on_staff_line: + flare_shift := 0.0; + else: % staffline_adjustment = anywhere + flare_shift := 0.25; + fi; + + char_box_adjust := flare_shift + 0.5; + + if d_ = dir_up: + set_char_box (0, + 0.60 staff_space#, + (flares + char_box_adjust) * staff_space#, + 0.10 staff_space#); + else: % d_ = dir_down + set_char_box (0.60 staff_space#, + 0, + 0.10 staff_space#, + (flares + char_box_adjust) * staff_space#); + fi; + + draw_mensural_outermost_flare (staffline_adjustment, d_); + + for flare_count := 2 step 1 until 4: + if flares >= flare_count: + draw_mensural_inner_flare (flare_shift + + flare_count - 0.5, + flare_count, d_); + fi; + endfor; + + if d_ = dir_down: + currentpicture := currentpicture xscaled -1 + yscaled -1; + fi; +enddef; + + +% 8th mensural flag, upwards, between staff lines +fet_beginchar ("8th Mensural Flag (up)", "mensuralu03"); + draw_mensural_flag (between_staff_lines, 1, dir_up); +fet_endchar; + + +% 8th mensural flag, upwards, on staff line +fet_beginchar ("8th Mensural Flag (up)", "mensuralu13"); + draw_mensural_flag (on_staff_line, 1, dir_up); +fet_endchar; + + +% 8th mensural flag, upwards, anywhere +fet_beginchar ("8th Mensural Flag (up)", "mensuralu23"); + draw_mensural_flag (anywhere, 1, dir_up); +fet_endchar; + + +% 8th mensural flag, downwards, between staff lines +fet_beginchar ("8th Mensural Flag (down)", "mensurald03"); + draw_mensural_flag (between_staff_lines, 1, dir_down); +fet_endchar; + + +% 8th mensural flag, downwards, on staff line +fet_beginchar ("8th Mensural Flag (down)", "mensurald13"); + draw_mensural_flag (on_staff_line, 1, dir_down); +fet_endchar; + + +% 8th mensural flag, downwards, anywhere +fet_beginchar ("8th Mensural Flag (down)", "mensurald23"); + draw_mensural_flag (anywhere, 1, dir_down); +fet_endchar; + + +% 16th mensural flag, upwards, between staff lines +fet_beginchar ("16th Mensural Flag (up)", "mensuralu04"); + draw_mensural_flag (between_staff_lines, 2, dir_up); +fet_endchar; + + +% 16th mensural flag, upwards, on staff line +fet_beginchar ("16th Mensural Flag (up)", "mensuralu14"); + draw_mensural_flag (on_staff_line, 2, dir_up); +fet_endchar; + + +% 16th mensural flag, upwards, anywhere +fet_beginchar ("16th Mensural Flag (up)", "mensuralu24"); + draw_mensural_flag (anywhere, 2, dir_up); +fet_endchar; + + +% 16th mensural flag, downwards, between staff lines +fet_beginchar ("16th Mensural Flag (down)", "mensurald04"); + draw_mensural_flag (between_staff_lines, 2, dir_down); +fet_endchar; + + +% 16th mensural flag, downwards, on staff line +fet_beginchar ("16th Mensural Flag (down)", "mensurald14"); + draw_mensural_flag (on_staff_line, 2, dir_down); +fet_endchar; + + +% 16th mensural flag, downwards, anywhere +fet_beginchar ("16th Mensural Flag (down)", "mensurald24"); + draw_mensural_flag (anywhere, 2, dir_down); +fet_endchar; + + +% 32th mensural flag, upwards, between staff lines +fet_beginchar ("32th Mensural Flag (up)", "mensuralu05"); + draw_mensural_flag (between_staff_lines, 3, dir_up); +fet_endchar; + + +% 32th mensural flag, upwards, on staff line +fet_beginchar ("32th Mensural Flag (up)", "mensuralu15"); + draw_mensural_flag (on_staff_line, 3, dir_up); +fet_endchar; + + +% 32th mensural flag, upwards, anywhere +fet_beginchar ("32th Mensural Flag (up)", "mensuralu25"); + draw_mensural_flag (anywhere, 3, dir_up); +fet_endchar; + + +% 32th mensural flag, downwards, between staff lines +fet_beginchar ("32th Mensural Flag (down)", "mensurald05"); + draw_mensural_flag (between_staff_lines, 3, dir_down); +fet_endchar; + + +% 32th mensural flag, downwards, on staff line +fet_beginchar ("32th Mensural Flag (down)", "mensurald15"); + draw_mensural_flag (on_staff_line, 3, dir_down); +fet_endchar; + + +% 32th mensural flag, downwards, anywhere +fet_beginchar ("32th Mensural Flag (down)", "mensurald25"); + draw_mensural_flag (anywhere, 3, dir_down); +fet_endchar; + + +% 64th mensural flag, upwards, between staff lines +fet_beginchar ("64th Mensural Flag (up)", "mensuralu06"); + draw_mensural_flag (between_staff_lines, 4, dir_up); +fet_endchar; + + +% 64th mensural flag, upwards, on staff line +fet_beginchar ("64th Mensural Flag (up)", "mensuralu16"); + draw_mensural_flag (on_staff_line, 4, dir_up); +fet_endchar; + + +% 64th mensural flag, upwards, anywhere +fet_beginchar ("64th Mensural Flag (up)", "mensuralu26"); + draw_mensural_flag (anywhere, 4, dir_up); +fet_endchar; + + +% 64th mensural flag, downwards, between staff lines +fet_beginchar ("64th Mensural Flag (down)", "mensurald06"); + draw_mensural_flag (between_staff_lines, 4, dir_down); +fet_endchar; + + +% 64th mensural flag, downwards, on staff line +fet_beginchar ("64th Mensural Flag (down)", "mensurald16"); + draw_mensural_flag (on_staff_line, 4, dir_down); +fet_endchar; + + +% 64th mensural flag, downwards, anywhere +fet_beginchar ("64th Mensural Flag (down)", "mensurald26"); + draw_mensural_flag (anywhere, 4, dir_down); +fet_endchar; + + +fet_endgroup ("flags"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-generic.mf b/muse2/share/scoreglyphs/feta-original/parmesan-generic.mf new file mode 100644 index 00000000..6ffb53aa --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-generic.mf @@ -0,0 +1,42 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-generic.mf -- implement generic stuff: include lots of files, +% but don't set dimensions. +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2002--2009 Juergen Reuter <reuter@ipd.uka.de> +% + + +if test = -1: + mode := smoke; +fi; + +mode_setup; + +staffsize# := design_size * pt#; + +input feta-macros; +input feta-params; + +input parmesan-macros; + + +font_x_height staff_space#; + + +fet_beginfont ("parmesan", design_size, "parmesanMusic"); + if test = 0: + input parmesan-rests; + input parmesan-heads; + input parmesan-clefs; + input parmesan-custodes + input parmesan-accidentals; + input parmesan-flags; + input parmesan-timesig; + input parmesan-scripts; + input parmesan-dots; + else: + + fi; +fet_endfont; diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-heads.mf b/muse2/share/scoreglyphs/feta-original/parmesan-heads.mf new file mode 100644 index 00000000..b897554d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-heads.mf @@ -0,0 +1,1492 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-heads.mf -- implement ancient note heads +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% +% Neo-mensural heads originally by +% Christian Mondrup and Mats Bengtsson +% + +save black_notehead_width; +numeric black_notehead_width; + +fet_begingroup ("noteheads"); + +% +% character aligment: +% +% The head is assumed to be vertically centered around (0, 0). +% The left-most edge of the head should touch the vertical line +% that goes though the point (0, 0). +% +% set_char_box() conventions: +% +% * breapth: Ignored (as far as I know). Should be set to 0. +% +% * width: Should match the head's width. +% +% * depth: Should match the bottom edge of the head. Affects vertical +% collision handling. +% +% * height: Should match the top edge of the head. Affects vertical +% collision handling. +% +% TODO: should depth/height include appendages/stems? + +overdone_heads = 0; +noteheight# := staff_space# + (1 + overdone_heads) * stafflinethickness#; +define_pixels (noteheight); + + +%%%%%%%% +% +% +% +% MENSURAL NOTATION +% +% +% + +def draw_neomensural_brevis (expr brevwid) = + save beamheight, head_width; + save holeheight, stem_width; + save serif_size, serif_protrude; + + head_width# = brevwid; + holeheight = 3 stafflinethickness; + stem_width = 1.4 stafflinethickness; + + define_pixels (head_width); + + set_char_box (0, head_width#, + noteheight# / 2, noteheight# / 2); + + 2 beamheight + holeheight = noteheight; + serif_size = (holeheight - stafflinethickness) / 2; + serif_protrude = 1.5 serif_size; + + z1l = (0, 0); + z2l = (0, -stafflinethickness / 2); + z3r = z2r + serif_size * (1, -1); + y4r = y3r; + x4r = head_width / 2; + z5l = z3l + (-serif_size, -serif_protrude); + + penpos1 (stem_width, 0); + penpos2 (stem_width, 0); + penpos3 (beamheight, 90); + penpos4 (beamheight, 90); + penpos5 (stem_width, 180); + + save pat_in, pat_out; + path pat_in, pat_out; + + pat_out := z4l + -- z3l{left} + .. z5l{down} + .. z5r{up} + -- z1l; + pat_out := pat_out + -- reverse pat_out yscaled -1; + pat_out := pat_out + -- reverse pat_out shifted (-x4r, 0) + xscaled -1 + shifted (x4l, 0) + -- cycle; + fill pat_out; + + pat_in := z4r + -- z3r{left} + .. z2r{up} + -- z1r; + pat_in := pat_in + -- reverse pat_in yscaled -1; + pat_in := pat_in + -- reverse pat_in shifted (-x4r, 0) + xscaled -1 + shifted (x4l, 0) + -- cycle; + unfill pat_in; + + penlabels (1, 2, 3, 4, 5); +enddef; + + +%%% This head does not seem to be used anywhere. Junk me? -- jr +def draw_neomensural_left_stemmed_head (expr wid) = + draw_neomensural_brevis (wid); + + x6 = x7 = stem_width / 2; + y6 = y5; + y7 = y5 - 2.25 staff_space; + + z17 = (x7, y7 - stem_width / 2); + + penpos6 (stem_width, 0); + penpos7 (stem_width, 0); + + fill z7l + -- z6l + -- z6r + -- z7r + .. z17 + .. cycle; + + penlabels (6, 7); + labels (17); +enddef; + + +%%% This head does not seem to be used anywhere. Junk me? -- jr +fet_beginchar ("Left stemmed notehead", "slneomensural"); + draw_neomensural_left_stemmed_head (2 staff_space#); +fet_endchar; + + +% +% Some sources (eg. Musix/OpusTeX) think that the appendage should be on +% the left, some say right. Right wins democratically. +% +def draw_neomensural_longa (expr wid) = + draw_neomensural_brevis (wid); + + save theta; + + x7r = head_width; + y7 = y5; + z6 - z7 = (stem_width / 2, -staff_space); + theta = angle (z6 - z7) + 90; + + penpos7 (stem_width, 0); + penpos6 (1.2 stem_width, theta); + + z7' = find_tangent (z6l, pat_out, + (x7l + 0.5 stem_width, y7l), + (x7l - 0.5 stem_width, y7l)); + + fill z7r + .. z6r{z6 - z7} + .. {z7 - z6}z6l + -- z7' + -- cycle; + + penlabels (6, 7); + labels (7'); +enddef; + + +% +% En wij presenteren U: de opvolgster van Emily +% +% (ze is wel breed) +% +fet_beginchar ("Neo-mensural maxima notehead", "sM3neomensural"); + draw_neomensural_longa (2.6 staff_space#); +fet_endchar; + + +fet_beginchar ("Neo-mensural longa notehead", "sM2neomensural"); + draw_neomensural_longa (2 staff_space#); +fet_endchar; + + +fet_beginchar ("Neo-mensural brevis notehead", "sM1neomensural"); + draw_neomensural_brevis (2 staff_space#); +fet_endchar; + + +def draw_neomensural_black_head (expr wid, height) = + save head_width; + save ne, nw, ne_dist, nw_dist; + pair ne, nw, ne_dist, nw_dist; + + head_width# = wid; + + set_char_box (0, head_width#, + height / 2, height / 2); + + charwx := head_width# / 2; + charwy := height / 2; + + y3 = y1 = 0; + x2 = x4 = (x1 + x3) / 2; + + pickup pencircle scaled blot_diameter; + + top y2 = h; + bot y4 = -d; + lft x1 = 0; + rt x3 = w; + + ne := unitvector (z2 - z1); + nw_dist := (ne rotated 90) * 0.5 blot_diameter; + nw := unitvector (z2 - z3); + ne_dist := (nw rotated -90) * 0.5 blot_diameter; + + fill lft z1{up} + .. (z1 + nw_dist){ne} + -- (z2 + nw_dist){ne} + .. top z2{right} + .. (z2 + ne_dist){-nw} + -- (z3 + ne_dist){-nw} + .. rt z3{down} + .. (z3 - nw_dist){-ne} + -- (z4 - nw_dist){-ne} + .. bot z4{left} + .. (z4 - ne_dist){nw} + -- (z1 - ne_dist){nw} + .. cycle; + + labels (1, 2, 3, 4); +enddef; + + +def draw_neomensural_open_head (expr wid, height)= + draw_neomensural_black_head (wid, height); + + save diamNW, diamSW; + + diamNW = length (z2 - z1) + blot_diameter; + diamSW = length (z4 - z1) + blot_diameter; + + save hole_widthNW, hole_widthSW; + + hole_widthNW = 0.34 diamNW ; + hole_widthSW + 2.6 linethickness = diamSW; + + (z7 + z5) / 2 = (w / 2, 0); + (z8 + z6) / 2 = (w / 2, 0); + z6 - z5 = hole_widthNW * unitvector (z2 - z1); + z7 - z6 = hole_widthSW * unitvector (z4 - z1); + + unfill z5 + -- z6 + -- z7 + -- z8 + -- cycle; + + labels (5, 6, 7, 8); +enddef; + + +% +% WL says the thin lines should be thinner. +% +fet_beginchar ("Harmonic notehead (Neo-mensural open)", "s0harmonic"); + draw_neomensural_open_head (1.3 staff_space#, 1.3 noteheight#); + charwx := head_width#; + charwy := 0; +fet_endchar; + + +fet_beginchar ("Harmonic notehead (Neo-mensural black)", "s2harmonic"); + draw_neomensural_black_head (1.3 staff_space#, 1.3 noteheight#); + charwx := head_width#; + charwy := 0; +fet_endchar; + + +fet_beginchar ("Neo-mensural semibrevis head", "s0neomensural"); + draw_neomensural_open_head (staff_space#, noteheight#); +fet_endchar; + + +fet_beginchar ("Neo-mensural minima head", "s1neomensural"); + draw_neomensural_open_head (staff_space#, noteheight#); +fet_endchar; + + +fet_beginchar ("Neo-mensural semiminima head", "s2neomensural"); + draw_neomensural_black_head (staff_space#, noteheight#); +fet_endchar; + + +def draw_mensural_brevis (expr wid) = + % TODO. For the moment, fall back to draw_neomensural_brevis. + draw_neomensural_brevis (wid); +enddef; + + +%%% This head does not seem to be used anywhere. Junk me? -- jr +def draw_mensural_left_stemmed_head (expr wid) = + draw_mensural_brevis (wid); + + x6 = x7 = stem_width / 2; + y6 = y5; + y7 = y5 - 2.25 staff_space; + + z17 = (x7, y7 - stem_width / 2); + + penpos6 (stem_width, 0); + penpos7 (stem_width, 0); + + fill z7l + -- z6l + -- z6r + -- z7r + .. z17 + .. cycle; + + penlabels (6, 7); + labels (17); +enddef; + + +def draw_mensural_longa (expr wid) = + draw_mensural_brevis (wid); + + x6 = x7 = head_width - stem_width / 2; + y6 = y5; + y7 = y5 - 2.25 staff_space; + + z17 = (x7, y7 - stem_width / 2); + + penpos6 (stem_width, 0); + penpos7 (stem_width, 0); + + fill z7l + -- z6l + -- z6r + -- z7r + .. z17 + .. cycle; + + penlabels (6, 7); + labels (17); +enddef; + + +%%% This head does not seem to be used anywhere. Junk me? -- jr +fet_beginchar ("Mensural left stemmed notehead", "slmensural"); + draw_mensural_left_stemmed_head (staff_space#); +fet_endchar; + + +fet_beginchar ("Mensural maxima notehead", "sM3mensural"); + draw_mensural_longa (2.0 staff_space#); +fet_endchar; + + +fet_beginchar ("Mensural longa notehead", "sM2mensural"); + draw_mensural_longa (staff_space#); +fet_endchar; + + +fet_beginchar ("Mensural brevis notehead", "sM1mensural"); + draw_mensural_brevis (staff_space#); +fet_endchar; + + +def draw_diamond_head (expr head_h, pen_w, pen_h, angle, open) = + save head_width, head_height; + save ellipse, ellipse_r; + path ellipse, ellipse_r, diamond_shape; + + head_height# = head_h; + head_width# / head_height# = tand (angle); + + set_char_box (0, head_width#, + head_height# / 2, head_height# / 2); + + charwx := head_width# / 2; + charwy := head_height# / 2 - linethickness#; + + define_pixels (head_width, head_height); + + ellipse := reverse fullcircle + xscaled (max (blot_diameter, pen_w * head_width)) + yscaled (max (blot_diameter, pen_h * head_width)) + rotated -angle; + + z1 = find_tangent_shift (((0, h) -- (0, -h)), ellipse, + (0, 0), (w / 2, 0)); + z2 = find_tangent_shift (((0, h) -- (w, h)), ellipse, + (w / 2, h), (w / 2, 0)); + z3 = find_tangent_shift (((w, h) -- (w, -h)), ellipse, + (w, 0), (w / 2, 0)); + z4 = find_tangent_shift (((0, -h) -- (w, -h)), ellipse, + (w / 2, -h), (w / 2, 0)); + + diamond_shape := get_subpath (ellipse, z1 - z4, z2 - z1, z1) + -- get_subpath (ellipse, z2 - z1, z3 - z2, z2) + -- get_subpath (ellipse, z3 - z2, z4 - z3, z3) + -- get_subpath (ellipse, z4 - z3, z1 - z4, z4) + -- cycle; + fill diamond_shape; + + if open: + save l; + path l[]; + + l12 := (directionpoint (z1 - z2) of ellipse) shifted z1 + -- (directionpoint (z1 - z2) of ellipse) shifted z2; + l23 := (directionpoint (z2 - z3) of ellipse) shifted z2 + -- (directionpoint (z2 - z3) of ellipse) shifted z3; + l34 := (directionpoint (z3 - z4) of ellipse) shifted z3 + -- (directionpoint (z3 - z4) of ellipse) shifted z4; + l41 := (directionpoint (z4 - z1) of ellipse) shifted z4 + -- (directionpoint (z4 - z1) of ellipse) shifted z1; + + unfill l12 intersectionpoint l23 + -- l23 intersectionpoint l34 + -- l34 intersectionpoint l41 + -- l41 intersectionpoint l12 + -- cycle; + fi; + + labels (1, 2, 3, 4); +enddef; + + +fet_beginchar ("Mensural semibrevis head", "s0mensural"); + draw_diamond_head (staff_space#, 0.15, 0.30, 30, true); +fet_endchar; + + +fet_beginchar ("Mensural minima head", "s1mensural"); + draw_diamond_head (staff_space#, 0.15, 0.30, 30, true); +fet_endchar; + + +fet_beginchar ("Mensural semiminima head", "s2mensural"); + draw_diamond_head (staff_space#, 0.15, 0.30, 30, false); +fet_endchar; + + +fet_beginchar ("Petrucci semibrevis head", "s0petrucci"); +% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true); + draw_neomensural_open_head (staff_space#, 1.8 staff_space#); +fet_endchar; + + +fet_beginchar ("Petrucci minima head", "s1petrucci"); +% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, true); + draw_neomensural_open_head (staff_space#, 1.8 staff_space#); +fet_endchar; + + +fet_beginchar ("Petrucci semiminima head", "s2petrucci"); +% draw_diamond_head (1.8 staff_space#, 0.15, 0.40, 30, false); + draw_neomensural_black_head (staff_space#, 1.8 staff_space#); +fet_endchar; + + +%%%%%%%% +% +% +% +% EDITIO VATICANA (including solesmes extensions) +% +% +% + +def vat_punctum_char (expr verbose_name, internal_name, + linea, cavum, straight, auctum, + d_up, up_shift, down_shift, mag) = + fet_beginchar (verbose_name, "s" & internal_name); + save a_b, b_h, a_w; + + a_b := 1.54; % b_h * a_b / a_w = wd / ht + b_h := 0.85; + a_w := 1.09; + + save a, beta, ht, wd; + + ht# = noteheight# * mag; + 2 beta = ht# * b_h; + a = beta * a_b; + wd# = 2 a / a_w; + black_notehead_width# := wd#; + + % direction + save d_, d_sign; + pair d_; + + if d_up: + d_ := up; + d_sign := 1; + else: + d_ := down; + d_sign := -1; + fi; + + % convexity and eccentricity + save u_convexity, u_eccentricity; + + if straight: + u_convexity# := -0.01 ht#; + u_eccentricity# := 0.0 ht#; % dummy + elseif auctum: + u_convexity# := -0.03 ht#; + u_eccentricity# := +0.25 ht#; + else: + u_convexity# := -0.05 ht#; + u_eccentricity# := 0.0 ht#; % dummy + fi; + + save convexity, eccentricity; + + convexity# := d_sign * u_convexity#; + eccentricity# := d_sign * u_eccentricity#; + + % y shift offset + save yoffs; + + if up_shift: + yoffs# := 0.08 ht#; + elseif down_shift: + yoffs# := -0.11 ht#; + else: + yoffs# := 0.00 ht#; + fi; + + define_pixels (convexity, eccentricity, yoffs, ht, wd); + + pickup pencircle scaled linethickness; + + save height, yoffs_bt, p, circle, circle_r; + path p, circle, circle_r; + + height# = 0.47 ht#; + yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#; + + define_pixels (height, yoffs_bt); + + circle := fullcircle scaled linethickness; + + x1 = x6; + x2 = x5; + x3 = x4; + y1 + height = y6; + y2 + height = y5; + y3 + height = y4; + + save box_top, box_bt; + + if auctum: + z1 = (0.00 wd + linethickness / 2, yoffs_bt); + z2 = (0.21 wd, yoffs_bt + convexity); + z3 = (0.42 wd - linethickness/ 2, + yoffs_bt + eccentricity); + box_top# = height# + yoffs_bt# + + max (0, convexity#, eccentricity#); + box_bt# = yoffs_bt# + + min (0, convexity#, eccentricity#); + p = z1 + .. {right}z2 + .. {d_}z3 + -- z4{-d_} + .. z5{left} + .. z6 + -- cycle; + else: + z1 = (0.00 wd + linethickness / 2, yoffs_bt); + z2 = (0.21 wd, yoffs_bt + convexity); + z3 = (0.42 wd - linethickness / 2, yoffs_bt); + box_top# = height# + yoffs_bt# + max (0, convexity#); + box_bt# = yoffs_bt# + min (0, convexity#); + p = z1 + .. z2 + .. z3 + -- z4 + .. z5 + .. z6 + -- cycle; + fi; + + labels (1, 2, 3, 4, 5, 6); + + save dirs; + pair dirs[]; + + dirs12 := direction (0 + epsilon) of p; + dirs2 := direction 1 of p; + dirs32 := direction (2 - epsilon) of p; + dirs45 := direction (3 + epsilon) of p; + dirs5 := direction 4 of p; + dirs65 := direction (5 - epsilon) of p; + + fill get_subpath (circle, down, dirs12, z1) + .. (bot z2){dirs2} + .. get_subpath (circle, dirs32, up, z3) + -- get_subpath (circle, up, dirs45, z4) + .. (top z5){dirs5} + .. get_subpath (circle, dirs65, down, z6) + -- cycle; + + if cavum: + save pat, t; + path pat[]; + numeric t[]; + + pat123 := ((directionpoint -dirs12 of circle) + shifted z1){dirs12} + .. (top z2){dirs2} + .. {dirs32}((directionpoint -dirs32 of circle) + shifted z3); + pat34 := lft z3 + -- lft z4; + pat456 := ((directionpoint -dirs45 of circle) + shifted z4){dirs45} + .. (bot z5){dirs5} + .. {dirs65}((directionpoint -dirs65 of circle) + shifted z6); + pat61 := rt z6 + -- rt z1; + + t61 := ypart (pat61 intersectiontimes pat123); + t12 := xpart (pat123 intersectiontimes pat34); + t34 := ypart (pat34 intersectiontimes pat456); + t45 := xpart (pat456 intersectiontimes pat61); + + unfill subpath (t61, t12) of pat123 + -- subpath (t34, t45) of pat456 + -- cycle; + fi; + + set_char_box (0.00 wd#, 0.42 wd#, + max (0, -box_bt#) + linethickness# / 2, + max (0, box_top#) + linethickness# / 2); + + if linea: + save linea_width, linea_height; + + linea_width# = 0.6 linethickness#; + linea_height# = 0.7 ht#; + + define_pixels (linea_width, linea_height); + + pickup pencircle scaled 0.6 linethickness; + + draw_rounded_block ((-0.10 wd - linea_width / 2, + -linea_height / 2), + (-0.10 wd + linea_width / 2, + +linea_height / 2), + 0.6 linethickness); + draw_rounded_block ((+0.52 wd - linea_width / 2, + -linea_height / 2), + (+0.52 wd + linea_width / 2, + +linea_height / 2), + 0.6 linethickness); + + set_char_box (0, 0.62 wd# + linea_width#, + linea_height# / 2, + linea_height# / 2); + + currentpicture := currentpicture + shifted (0.10 wd + linea_width / 2, 0); + fi; + fet_endchar; +enddef; + + +def plica_char (expr verbose_name, internal_name, + d_up, mag) = + fet_beginchar (verbose_name, "s" & internal_name); + save a_b, b_h, a_w; + + a_b := 1.54; % b_h * a_b / a_w = wd / ht + b_h := 0.85; + a_w := 1.09; + + save a, beta, ht, wd; + + ht# = noteheight# * mag; + 2 beta = ht# * b_h; + a = beta * a_b; + wd# = 2 a / a_w; + black_notehead_width# := wd#; + + % direction + save d_, d_sign; + pair d_; + + if d_up: + d_ := up; + d_sign := 1; + else: + d_ := down; + d_sign := -1; + fi; + + % convexity and eccentricity + save convexity, eccentricity; + + convexity# := d_sign * -0.10 ht#; + eccentricity# := d_sign * -0.12 ht#; + + % y shift offset + save yoffs; + + yoffs# := -0.11 ht#; + + define_pixels (convexity, eccentricity, yoffs, ht, wd); + + pickup pencircle scaled linethickness; + + save height, yoffs_bt, p, circle, circle_r; + path p, circle, circle_r; + + height# = 0.47 ht#; + yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#; + + define_pixels (height, yoffs_bt); + + circle := fullcircle scaled linethickness; + + x1 = x6; + x2 = x5; + x3 = x4; + y1 + height = y6; + y2 + height = y5; + y3 + height = y4; + + save box_top, box_bt; + + z1 = (0.00 wd + linethickness / 2, yoffs_bt); + z2 = (0.21 wd, yoffs_bt + convexity); + z3 = (0.42 wd - linethickness/ 2, yoffs_bt + eccentricity); + box_top# = height# + yoffs_bt# + + max (0, convexity#, eccentricity#); + box_bt# = yoffs_bt# + + min (0, convexity#, eccentricity#); + p = z1 + .. z2{right} + .. z3 + -- z4 + .. z5{left} + .. z6 + -- cycle; + + labels (1, 2, 3, 4, 5, 6); + + save dirs; + pair dirs[]; + + dirs12 := direction (0 + epsilon) of p; + dirs2 := direction 1 of p; + dirs32 := direction (2 - epsilon) of p; + dirs45 := direction (3 + epsilon) of p; + dirs5 := direction 4 of p; + dirs65 := direction (5 - epsilon) of p; + + fill get_subpath (circle, down, dirs12, z1) + .. (bot z2){dirs2} + .. get_subpath (circle, dirs32, up, z3) + -- get_subpath (circle, up, dirs45, z4) + .. (top z5){dirs5} + .. get_subpath (circle, dirs65, down, z6) + -- cycle; + + pickup pencircle scaled 0.6 linethickness; + + save stem_bt; + + set_char_box (0.00 wd#, 0.42 wd#, + max (0, -box_bt#) + linethickness# / 2, + max (0, box_top#) + linethickness# / 2); + + fet_endchar; +enddef; + + +def epiphonus_char (expr verbose_name, internal_name, + left_stem, d_up, down_shift, mag) = + fet_beginchar (verbose_name, "s" & internal_name); + save a_b, b_h, a_w; + + a_b := 1.54; % b_h * a_b / a_w = wd / ht + b_h := 0.85; + a_w := 1.09; + + save a, beta, ht, wd; + + ht# = noteheight# * mag; + 2 beta = ht# * b_h; + a = beta * a_b; + wd# = 2 a / a_w; + black_notehead_width# := wd#; + + % direction + save d_, d_sign; + pair d_; + + if d_up: + d_ := up; + d_sign := 1; + else: + d_ := down; + d_sign := -1; + fi; + + % convexity and eccentricity + save convexity; + + convexity# := d_sign * -0.05ht#; + + % y shift offset + save yoffs; + + if down_shift: + yoffs# := -0.11 ht#; + else: + yoffs# := 0.00 ht#; + fi; + + define_pixels (convexity, yoffs, ht, wd); + + pickup pencircle scaled linethickness; + + save height, yoffs_bt, p, circle, circle_r; + path p, circle, circle_r; + + height# = 0.47 ht#; + yoffs_bt# = yoffs# - 0.5 height# - 0.25 convexity#; + + define_pixels (height, yoffs_bt); + + circle := fullcircle scaled linethickness; + + x1 = x6; + x2 = x5; + x3 = x4; + y1 + height = y6; + y2 + height = y5; + y3 + height = y4; + + save box_top, box_bt; + + z1 = (0.00 wd + linethickness / 2, yoffs_bt - 2.5 convexity); + z2 = (0.06 wd, yoffs_bt + 1.4 convexity); + z3 = (0.42 wd - linethickness / 2, yoffs_bt - 1.0 convexity); + box_top# = height# + yoffs_bt# + + max (-1.0 convexity#, 1.4 convexity#, 0); + box_bt# = yoffs_bt# + + min (-1.0 convexity#, 1.4 convexity#, 0); + p = z1{-d_} + .. {curl 1}z2{right} + .. z3 + -- z4 + .. {left}z5{curl 1} + .. {d_}z6 + -- cycle; + + labels (1, 2, 3, 4, 5, 6); + + save dirs; + pair dirs[]; + + dirs12 := direction (0 + epsilon) of p; + dirs21 := direction (1 - epsilon) of p; + dirs23 := direction (1 + epsilon) of p; + dirs32 := direction (2 - epsilon) of p; + dirs45 := direction (3 + epsilon) of p; + dirs54 := direction (4 - epsilon) of p; + dirs56 := direction (4 + epsilon) of p; + dirs65 := direction (5 - epsilon) of p; + + fill get_subpath (circle, down, dirs12, z1) + .. get_subpath (circle, dirs21, dirs23, z2) + .. get_subpath (circle, dirs32, up, z3) + -- get_subpath (circle, up, dirs45, z4) + .. get_subpath (circle, dirs54, dirs56, z5) + .. get_subpath (circle, dirs65, down, z6) + -- cycle; + + save stem_bt; + + if left_stem: + pickup pencircle scaled 0.6 linethickness; + + lft x11 = x1 - linethickness / 2; + bot y11 = yoffs - 1.1 ht - linethickness / 2; + x12 = x11; + y12 = y1; + + draw_rounded_block (bot lft z11, top rt z12, + 0.6 linethickness); + stem_bt# = yoffs# - 1.1 ht#; + + labels (11, 12); + else: + stem_bt# = 0; + fi; + + set_char_box (0.00 wd#, 0.42 wd#, + max (0, -box_bt#, -stem_bt#) + linethickness# / 2, + max (0, box_top#) + linethickness# / 2); + fet_endchar; +enddef; + + +def inclinatum_char (expr verbose_name, internal_name, + small, stropha, auctum) = + fet_beginchar (verbose_name, "s" & internal_name); + save ht, alpha; + + alpha := 35; + + if small: + ht# = 0.50 noteheight#; + else: + ht# = 0.80 noteheight#; + fi; + + draw_diamond_head (ht#, 0, 0, alpha, false); + + save off_angle; + + off_angle := alpha + 15; + + save stropha_ellipse, auctum_hook, circle; + path stropha_ellipse, auctum_hook, circle; + + circle := reverse fullcircle scaled linethickness; + + stropha_ellipse := fullcircle xscaled 0.25 head_height + yscaled 0.55 head_height + rotated alpha; + + z11 = z12 + + linethickness / 2 * dir (180 - off_angle) + - directionpoint dir (90 - off_angle) + of stropha_ellipse; + z12 = directionpoint -dir (90 - off_angle) of diamond_shape + + linethickness / 2 * dir (180 - off_angle); + z13 = (0, -0.5 head_height + linethickness); + + auctum_hook := z12{-dir (90 - off_angle)} + .. {dir (90 + alpha)}z13; + + labels (12); + + if (stropha and not auctum): + clearit; + + save t_in, t_out; + + t_in := xpart ((stropha_ellipse shifted z11) + intersectiontimes + get_subpath (diamond_shape, + left, up, + (0, 0))); + t_out := xpart ((stropha_ellipse shifted z11) + intersectiontimes + get_subpath (diamond_shape, + up, right, + (0, 0))); + + % the addition or subtraction of `1' is necessary + % so that we get the right starting point + fill get_subpath_i (diamond_shape, + dir (angle (z2 - z1) - 1), + dir (angle (z1 - z4) + 1), + (0, 0)) + -- get_subpath (stropha_ellipse, + direction t_in of stropha_ellipse, + direction t_out of stropha_ellipse, + z11) + -- cycle; + + labels (11); + fi; + + if (auctum and not stropha): + clearit; + + fill get_subpath (diamond_shape, + left, + -dir (90 - off_angle), + (0, 0)) + .. get_subpath (circle, + dir (90 + alpha), + -dir (90 + alpha), + z13) + .. get_subpath (circle, + dir (90 - off_angle), + right, + z12) + -- cycle; + + labels (13); + fi; + + if (auctum and stropha): + clearit; + + save t; + + t := xpart ((stropha_ellipse shifted z11) + intersectiontimes + get_subpath (diamond_shape, up, right, + (0, 0))); + + % the addition or subtraction of `1' is necessary + % so that we get the right starting point + fill get_subpath_i (diamond_shape, + dir (angle (z2 - z1) - 1), + -dir (90 - off_angle), + (0, 0)) + .. get_subpath (circle, + dir (90 + alpha), + -dir (90 + alpha), + z13) + .. get_subpath (stropha_ellipse, + dir (90 - off_angle), + direction t of stropha_ellipse, + z11) + -- cycle; + + labels (11, 13); + fi; + fet_endchar; +enddef; + + +% punctum +vat_punctum_char ("Ed. Vat. punctum", "vaticana.punctum", + false, false, false, false, + false, false, false, 1.0); + + +% punctum cavum (for OpusTeX compatibility) +vat_punctum_char ("Ed. Vat. punctum cavum", "vaticana.punctum.cavum", + false, true, false, false, + false, false, false, 1.0); + + +% linea punctum (for OpusTeX compatibility) +vat_punctum_char ("Ed. Vat. linea punctum", "vaticana.linea.punctum", + true, false, false, false, + false, false, false, 1.0); + + +% linea punctum cavum (for OpusTeX compatibility) +vat_punctum_char ("Ed. Vat. linea punctum cavum", "vaticana.linea.punctum.cavum", + true, true, false, false, + false, false, false, 1.0); + + +% punctum inclinatum +inclinatum_char ("Ed. Vat. inclinatum", "vaticana.inclinatum", + false, false, false); + + +% pes lower punctum +vat_punctum_char ("Ed. Vat. pes lower punctum", "vaticana.lpes", + false, false, true, false, + true, false, false, 1.0); + + +% pes lower punctum +vat_punctum_char ("Ed. Vat. pes var lower punctum", "vaticana.vlpes", + false, false, true, false, + true, false, true, 1.0); + + +% pes upper punctum +vat_punctum_char ("Ed. Vat. pes upper punctum", "vaticana.upes", + false, false, true, false, + false, false, false, 1.0); + + +% pes upper punctum (shifted variation) +% +% This note head is used instead of the regular pes upper punctum to +% avoid collision with the lower punctum note of the pes when the upper +% punctum sits directly on top of the lower punctum. +% +vat_punctum_char ("Ed. Vat. var pes upper punctum", "vaticana.vupes", + false, false, true, false, + false, true, false, 1.0); + + +% small punctum as used in epiphonus +vat_punctum_char ("Ed. Vat. plica", "vaticana.plica", + false, false, false, false, + false, false, false, 0.6); + + +% small punctum as used in epiphonus +plica_char ("Ed. Vat. var plica", "vaticana.vplica", + false, 0.6); + + +% eccentric punctum as used in epiphonus +epiphonus_char ("Ed. Vat. epiphonus", "vaticana.epiphonus", + false, true, false, 1.0); + + +% eccentric punctum as used in epiphonus (shifted variation) +% +% This note head is used instead of the regular epiphonus punctum to +% avoid collision with the plica head when the plica sits directly on +% top of the lower head. +% +epiphonus_char ("Ed. Vat. var epiphonus", "vaticana.vepiphonus", + false, true, true, 1.0); + + +% small punctum as used in cephalicus +vat_punctum_char ("Ed. Vat. rev. plica", "vaticana.reverse.plica", + false, false, false, false, + true, false, false, 0.6); + + +% small punctum as used in cephalicus +plica_char ("Ed. Vat. rev. var plica", "vaticana.reverse.vplica", + true, 0.6); + + +% eccentric punctum as used in cephalicus; without left stem +epiphonus_char ("Ed. Vat. inner cephalicus", "vaticana.inner.cephalicus", + false, false, false, 1.0); + + +% eccentric punctum as used in cephalicus; with left stem +epiphonus_char ("Ed. Vat. cephalicus", "vaticana.cephalicus", + true, false, false, 1.0); + + +% quilisma +fet_beginchar ("Ed. Vat. quilisma", "svaticana.quilisma"); + save a_b, b_h, a_w; + + a_b := 1.54; % b_h * a_b / a_w = wd / ht + b_h := 0.85; + a_w := 1.09; + + save a, beta, ht, wd; + + ht# = noteheight#; + 2 beta = ht# * b_h; + a = beta * a_b; + wd# = 2 a / a_w; + + set_char_box (0, 0.42 wd#, 0.28 ht#, 0.36 ht#); + + black_notehead_width# := wd#; + + define_pixels (ht, wd); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled linethickness + yscaled 0.44 ht; + pickup pencircle transformed T; + ellipse := reverse fullcircle transformed T; + + z1 = (rt 0.00 wd, top -0.28 ht); + z2 = (0.11 wd, -0.14 ht); + z3 = (0.12 wd, +0.03 ht); + z4 = (0.25 wd, -0.09 ht); + z5 = (0.25 wd, +0.08 ht); + z6 = (lft 0.42 wd, -0.04 ht); + z7 = (lft 0.40 wd, bot +0.36 ht); + + fill get_subpath (ellipse, z1 - z2, z2 - z1, z1) + -- get_subpath (ellipse, z2 - z1, z1 - z2, z2) + -- cycle; + fill get_subpath (ellipse, z3 - z4, z4 - z3, z3) + -- get_subpath (ellipse, z4 - z3, z3 - z4, z4) + -- cycle; + fill get_subpath (ellipse, z5 - z6, z6 - z5, z5) + -- point 0 of get_subpath (ellipse, z6 - z5, z5 - z6, z6) + -- get_subpath (ellipse, z7 - z6, z6 - z7, z7) + -- get_subpath (ellipse, z6 - z7, z5 - z6, z6) + -- cycle; + + labels (1, 2, 3, 4, 5, 6, 7); +fet_endchar; + + +% solesmes punctum inclinatum parvum +inclinatum_char ("Solesmes punctum inclinatum parvum", "solesmes.incl.parvum", + true, false, false); + + +% solesmes punctum auctum ascendens +vat_punctum_char ("Solesmes punctum auctum ascendens", "solesmes.auct.asc", + false, false, false, true, + true, false, false, 1.0); + + +% solesmes punctum auctum descendens +vat_punctum_char ("Solesmes punctum auctum descendens", "solesmes.auct.desc", + false, false, false, true, + false, false, false, 1.0); + + +% solesmes punctum inclinatum auctum +inclinatum_char ("Solesmes punctum incl. auctum", "solesmes.incl.auctum", + false, false, true); + + +% solesmes stropha +inclinatum_char ("Solesmes stropha", "solesmes.stropha", + false, true, false); + + +% solesmes stropha aucta +inclinatum_char ("Solesmes stropha aucta", "solesmes.stropha.aucta", + false, true, true); + + +% solesmes oriscus +fet_beginchar ("Solesmes oriscus", "ssolesmes.oriscus"); + save a_b, b_h, a_w; + + a_b := 1.54; % b_h * a_b / a_w = wd / ht + b_h := 0.85; + a_w := 1.09; + + save a, beta, ht, wd; + + ht# = noteheight#; + 2 beta = ht# * b_h; + a = beta * a_b; + wd# = 2 a / a_w; + black_notehead_width# := wd#; + + save convexity; + + convexity# = +0.05 ht#; + + define_pixels (ht, wd, convexity); + + set_char_box (0.00 wd#, 0.50 wd#, + 0.25 ht# + convexity#, 0.25 ht# + convexity#); + + z1 = (0.00 wd + blot_diameter / 2, -convexity); + z2 = (1/6 wd, +convexity); + z3 = (2/6 wd, -convexity); + z4 = (0.50 wd - blot_diameter / 2, +convexity); + + + save height; + + height = 2 ypart (directionpoint right of (z1 + .. z2 + .. z3 + .. z4)); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled blot_diameter + yscaled (h + d - height); + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + % Adjust vertical coordinates to touch bounding box. + y1 := top -d; + y4 := bot h; + + save d_; + pair d_; + + d_ := direction 0 of (z1 + .. z2 + .. z3 + .. z4); + + fill get_subpath (ellipse, -d_, d_, z1) + .. bot z2 + .. bot z3 + .. get_subpath (ellipse, d_, -d_, z4) + .. top z3 + .. top z2 + .. cycle; + + labels (1, 2, 3, 4); +fet_endchar; + + +%%%%%%%% +% +% +% +% EDITIO MEDICAEA +% +% +% + +% inclinatum +fet_beginchar ("Ed. Med. inclinatum", "smedicaea.inclinatum"); + draw_diamond_head (1.2 staff_space#, 0, 0, 35, false); +fet_endchar; + + +def med_punctum_char (expr verbose_name, internal_name, + left_up_stem, left_down_stem) = + fet_beginchar (verbose_name, "s" & internal_name); + save a, ht, wd; + + ht# = 2 staff_space#; + wd# = ht#; + black_notehead_width# := wd#; + + define_pixels (ht, wd); + + save ellipse; + path ellipse; + + ellipse := fullcircle xscaled blot_diameter + yscaled 0.50 ht; + + z1 = (0.00 wd + blot_diameter / 2, 0); + z2 = (0.4 wd - blot_diameter / 2, 0); + + labels (1, 2); + + pickup pencircle scaled linethickness; + + if left_down_stem: + z4 = (0.00 wd + linethickness / 2, -1.25 ht); + + fill get_subpath (ellipse, left, down, z1) + -- top lft z4{down} + .. z4{right} + .. top rt z4{up} + -- (rt x4, -.5 ht / 2) + -- get_subpath (ellipse, right, left, z2) + -- cycle; + + labels (4); + + set_char_box (0.0, 0.4 wd#, 1.25 ht#, 0.25 ht#); + elseif left_up_stem: + z4 = (0.00 wd + linethickness / 2, +1.25 ht); + + fill get_subpath (ellipse, down, right, z1) + -- get_subpath (ellipse, right, left, z2) + -- (rt x4, .5 ht / 2) + -- bot rt z4{up} + .. z4{left} + .. bot lft z4{down} + -- cycle; + + labels (4); + + set_char_box (0.0, 0.4 wd#, 0.25 ht#, 1.25 ht#); + else: + fill get_subpath (ellipse, left, right, z1) + -- get_subpath (ellipse, right, left, z2) + -- cycle; + + set_char_box (0.0, 0.4 wd#, 0.25 ht#, 0.25 ht#); + fi; + + fet_endchar; +enddef; + + +% punctum +med_punctum_char ("Ed. Med. punctum", "medicaea.punctum", + false, false); + + +% left up-stemmed punctum +med_punctum_char ("Ed. Med. reverse virga", "medicaea.rvirga", + true, false); + + +% virga (i.e. left down-stemmed punctum) +med_punctum_char ("Ed. Med. virga", "medicaea.virga", + false, true); + + +%%%%%%%% +% +% +% +% HUFNAGEL +% +% +% + +def huf_punctum_char (expr verbose_name, internal_name, + down_stem) = + fet_beginchar (verbose_name, "s" & internal_name); + save alpha; + + alpha = 55; + + draw_diamond_head (staff_space#, 0, 0, alpha, false); + + if down_stem: + set_char_box (0, head_width#, + 1.5 staff_space#, head_height# / 2); + + save ellipse; + path ellipse; + + ellipse := reverse fullcircle xscaled blot_diameter + yscaled 0.7 staff_space + rotated -alpha; + + z11 = (head_width / 2, 0); + z12 = find_tangent_shift (((0, -d) -- (w, -d)), ellipse, + (w / 2, -d), (w / 2, 0)); + + fill get_subpath (ellipse, up, down, z11) + -- get_subpath (ellipse, down, up, z12) + -- cycle; + + labels (11, 12); + fi; + fet_endchar; +enddef; + + +% punctum +huf_punctum_char ("Hufnagel punctum", "hufnagel.punctum", false) + + +% virga +huf_punctum_char ("Hufnagel virga", "hufnagel.virga", true) + + +% pes lower punctum +fet_beginchar ("Hufnagel pes lower punctum", "shufnagel.lpes") + save width, height, alpha; + + width# = 2 * staff_space#; + height# = 0.7 * staff_space#; + alpha = 35; + + set_char_box (0, width#, height# / 2, height# / 2); + + define_pixels (width, height); + + save circle; + path circle; + + circle := reverse fullcircle scaled linethickness; + + pickup pencircle scaled linethickness; + + rt x3 = -lft x1 = width / 2; + y2 = y3 = height / 2; + y1 = y4 = -height / 2; + + tand (alpha) * (y2 - y1) = x2 - x1 = x3 - x4; + + fill get_subpath (circle, left, z2 - z1, z1) + -- get_subpath (circle, z2 - z1, right, z2) + -- get_subpath (circle, right, z4 - z3, z3) + -- get_subpath (circle, z4 - z3, left, z4) + -- cycle; + + currentpicture := currentpicture shifted (width/2, 0); + +% labels (1, 2, 3, 4); +fet_endchar; + + +fet_endgroup ("noteheads"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-macros.mf b/muse2/share/scoreglyphs/feta-original/parmesan-macros.mf new file mode 100644 index 00000000..94d728a3 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-macros.mf @@ -0,0 +1,215 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-macros.mf -- macros for parmesan font +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% + + +% +% Find point on `curve' which gives the tangent between point `p' +% and `curve'. To guide the search, two auxiliary points must be +% specified, `p_in' and `p_out'. The line between `p' and `p_in' +% must intersect `curve', while the line between `p' and `p_out' +% must not. +% +def find_tangent (expr p, curve, p_in, p_out) = + begingroup; + save mid, t, t_good, in, out; + pair mid, in, out; + + in := p_in; + out := p_out; + + forever: + mid := 0.5 [in, out]; + exitif abs (out - mid) <= eps; + t := xpart (curve intersectiontimes (p -- mid)); + if t > 0: + in := mid; + t_good := t; + else: + out := mid; + fi; + endfor; + + point t_good of curve + endgroup +enddef; + + +% +% Shift `curve' along the line given by the auxiliary points `p_in' +% and `p_out' until `line' is a tangent, and return the shift. +% If `curve' is shifted to position `p_in', it must intersect +% `line', while shifted to `p_out' it must not. +% +def find_tangent_shift (expr line, curve, p_in, p_out) = + begingroup; + save mid, t, in, out; + pair mid, in, out; + + in := p_in; + out := p_out; + + forever: + mid := 0.5 [in, out]; + exitif abs (out - mid) <= eps; + t := xpart ((curve shifted mid) intersectiontimes line); + if t > 0: + in := mid; + else: + out := mid; + fi; + endfor; + + mid + endgroup +enddef; + + +% +% Get subpath specified by `dir_in' and `dir_out' of `curve' +% which is then shifted by `offset'. Assure that result has +% the same orientation as `curve'. +% +def get_subpath (expr curve, dir_in, dir_out, offset) = + begingroup; + save t_in, t_out; + + t_in := directiontime dir_in of curve; + t_out := directiontime dir_out of curve; + + if t_in > t_out: + t_out := t_out + length curve; + fi; + + (subpath (t_in, t_out) of curve) shifted offset + endgroup +enddef; + + +% +% Get point specified by `dir_' of `curve' which is then +% shifted by `offset'. +% +def get_subpoint (expr curve, dir_, offset) = + (directionpoint dir_ of curve) shifted offset +enddef; + + +% +% This is the same as `get_subpath', except that the time values +% used to construct the resulting subpath are rounded to integers. +% +def get_subpath_i (expr curve, dir_in, dir_out, offset) = + begingroup; + save t_in, t_out; + + t_in := directiontime dir_in of curve; + t_out := directiontime dir_out of curve; + + if t_in > t_out: + t_out := t_out + length curve; + fi; + + (subpath (floor (t_in + 0.5), floor (t_out + 0.5)) of curve) + shifted offset + endgroup +enddef; + + +% +% Find envelope cusp created by `object' moved along `curve', using +% step value `s' for initial intermediate points. `s' must be small +% enough so that this macro finds at least one point on the envelope +% between the `entrance' and `exit' points of the cusp which has +% a significantly different direction vector. +% +% This function returns a time value on `curve'; if there is no +% cusp, it returns -1. +% +def find_envelope_cusp (expr object, curve, s) = + begingroup; + save mid, p, t, t_good, delta, start, stop, do_exit; + pair p[]; + boolean do_exit; + + p0 := (directionpoint (direction 0 of curve) of object) + shifted (point 0 of curve); + p1 := (directionpoint (direction s of curve) of object) + shifted (point s of curve); + + t := s; + + forever: + t := t + s; + exitif t >= length curve; + + p2 := (directionpoint (direction t of curve) of object) + shifted (point t of curve); + if p2 <> p1: + delta := angle (p2 - p1) - angle (p1 - p0); + if delta > 180: + delta := delta - 360; + fi; + + % we check for a direction change by more than + % than 45 degrees + if abs (delta) >= 45: + do_exit := true; + else: + do_exit := false; + fi; + + p0 := p1; + p1 := p2; + fi; + + % having `exitif' within an if-clause doesn't work + exitif do_exit; + endfor; + + if t >= length curve: + t_good := -1; + else: + % the wanted point lies between `t - s' and `t' + start := t - s; + stop := t; + t_good := start; + + forever: + mid := 0.5 [start, stop]; + exitif abs (stop - mid) <= eps; + + p0 := (directionpoint (direction start of curve) + of object) shifted (point start of curve); + p1 := (directionpoint (direction mid of curve) + of object) shifted (point mid of curve); + p2 := (directionpoint (direction stop of curve) + of object) shifted (point stop of curve); + + exitif (length (p1 - p0) = 0) + or (length (p2 - p1) = 0); + + delta := angle (p2 - p1) - angle (p1 - p0); + if delta > 180: + delta := delta - 360; + fi; + + if abs (delta) >= 45: + stop := mid; + t_good := mid; + else: + start := mid; + t_good := stop; + fi; + endfor; + fi; + + t_good + endgroup +enddef; + +% EOF diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-rests.mf b/muse2/share/scoreglyphs/feta-original/parmesan-rests.mf new file mode 100644 index 00000000..060307db --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-rests.mf @@ -0,0 +1,418 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-rests.mf -- implement ancient rests +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2001--2009 Juergen Reuter <reuter@ipd.uka.de> +% +% Neo-mensural rests originally by +% Christian Mondrup and Mats Bengtsson. +% + +fet_begingroup ("rests") + + +%%%%%%%% +% +% +% +% NEO-MENSURAL NOTATION +% +% +% + +% Neo-mensural longa and breve are identical with default longa and breve. + +neomens_block_rest_x# = 2/5 staff_space#; +neomens_block_rest_y# = 1/1 staff_space#; +neomens_half_block_rest_y# = 5/8 staff_space#; + +define_pixels (neomens_block_rest_x, + neomens_block_rest_y, + neomens_half_block_rest_y); + + +def neomens_half_block_rest = + draw_block ((0, 0), + (neomens_block_rest_x, neomens_half_block_rest_y)); +enddef; + + +fet_beginchar ("Neo-mensural maxima rest", "M3neomensural"); + set_char_box (0, 3 neomens_block_rest_x#, + neomens_block_rest_y#, neomens_block_rest_y#); + + draw_block ((0, -neomens_block_rest_y), + (neomens_block_rest_x, neomens_block_rest_y)); + addto currentpicture also currentpicture + shifted (2 neomens_block_rest_x, 0); +fet_endchar; + + +fet_beginchar ("Neo-mensural longa rest", "M2neomensural"); + set_char_box (0, neomens_block_rest_x#, + neomens_block_rest_y#, neomens_block_rest_y#); + + draw_block ((0, -neomens_block_rest_y), + (neomens_block_rest_x, neomens_block_rest_y)); +fet_endchar; + + +fet_beginchar ("Neo-mensural breve rest", "M1neomensural"); + set_char_box (0, neomens_block_rest_x#, + 0, neomens_block_rest_y#); + + draw_block ((0, 0), + (neomens_block_rest_x, neomens_block_rest_y)); +fet_endchar; + + +fet_beginchar ("Neo-mensural whole rest", "0neomensural"); + set_char_box (0, neomens_block_rest_x#, + neomens_half_block_rest_y#, 0); + + neomens_half_block_rest; + currentpicture := + currentpicture shifted (0, -neomens_half_block_rest_y); +fet_endchar; + + +fet_beginchar ("Neo-mensural half rest", "1neomensural"); + set_char_box (0, neomens_block_rest_x#, + 0, neomens_half_block_rest_y#); + + neomens_half_block_rest; +fet_endchar; + + +neomensrestsize# = 0.8 staff_space#; + + +fet_beginchar ("Neo-mensural 4th rest", "2neomensural"); + set_char_box (0, neomensrestsize#, + 0, neomensrestsize#); + + pickup pencircle scaled 2 stafflinethickness; + + lft x1 = 0; + bot y1 = 0; + lft x2 = lft x3 = 0; + top y2 = top y3 = h; + rt x4 = w; + bot y4 = h / 2; + + z11 = z1 - stafflinethickness * unitvector (z2 - z1); + z14 = z4 + stafflinethickness * unitvector (z4 - z3); + + penpos1 (2 stafflinethickness, 0); + penpos2 (2 stafflinethickness, 0); + penpos3 (2 stafflinethickness, angle (z4 - z3) - 90); + penpos4 (2 stafflinethickness, angle (z4 - z3) - 90); + + fill z1l + -- z2l + -- z2r + -- z1r + .. z11 + .. z1l + .. cycle; + fill z3l + -- z4l + .. z14 + .. z4r + -- z3r + .. z2l{up} + .. z3l + .. cycle; + + penlabels (1, 2, 3, 4); + labels (11, 14); +fet_endchar; + + +fet_beginchar ("Neo-mensural 8th rest", "3neomensural"); + set_char_box (0, neomensrestsize#, + 0, neomensrestsize#); + + pickup pencircle scaled 2 stafflinethickness; + + rt x1 = w; + bot y1 = 0; + rt x2 = rt x3 = w; + top y2 = top y3 = h; + lft x4 = 0; + bot y4 = h / 2; + + z11 = z1 - stafflinethickness * unitvector (z2 - z1); + z14 = z4 + stafflinethickness * unitvector (z4 - z3); + + penpos1 (2 stafflinethickness, 0); + penpos2 (2 stafflinethickness, 0); + penpos3 (2 stafflinethickness, angle (z4 - z3) - 90); + penpos4 (2 stafflinethickness, angle (z4 - z3) - 90); + + fill z1l + -- z2l + -- z2r + -- z1r + .. z11 + .. z1l + .. cycle; + fill z3l + -- z4l + .. z14 + .. z4r + -- z3r + .. z2r{down} + .. z3l + .. cycle; + + penlabels (1, 2, 3, 4); + labels (11, 14); +fet_endchar; + + +fet_beginchar ("Neo-mensural 16th rest", "4neomensural"); + set_char_box (0, neomensrestsize#, + 0, staff_space#); + + pickup pencircle scaled 2 stafflinethickness; + + rt x1 = w; + bot y1 = 0; + rt x2 = w; + top y2 = h; + + rt x3 = w; + top y3 = h; + lft x4 = 0; + bot y4 = h / 2; + rt x5 = w; + top y5 = 5/8 h; + lft x6 = 0; + bot y6 = h / 8; + + z11 = z1 - stafflinethickness * unitvector (z2 - z1); + z14 = z4 + stafflinethickness * unitvector (z4 - z3); + z16 = z6 + stafflinethickness * unitvector (z6 - z5); + + penpos1 (2 stafflinethickness, 0); + penpos2 (2 stafflinethickness, 0); + penpos3 (2 stafflinethickness, angle (z4 - z3) - 90); + penpos4 (2 stafflinethickness, angle (z4 - z3) - 90); + penpos5 (2 stafflinethickness, angle (z6 - z5) - 90); + penpos6 (2 stafflinethickness, angle (z6 - z5) - 90); + + fill z1l + -- z2l + -- z2r + -- z1r + .. z11 + .. z1l + .. cycle; + fill z3l + -- z4l + .. z14 + .. z4r + -- z3r + .. z2r{down} + .. z3l + .. cycle; + fill z5l + -- z6l + .. z16 + .. z6r + -- z5r + -- z5l + -- cycle; + + penlabels (1, 2, 3, 4, 5, 6); + labels (11, 14, 16); +fet_endchar; + + +%%%%%%%% +% +% +% +% MENSURAL NOTATION +% +% +% + +pen_width# = 0.3 staff_space#; +pen_height# = 0; +pen_rotation = 30; +slight_pen_rotation = 15; + +mens_block_rest_y# = 1/1 staff_space#; +mens_half_block_rest_y# = 5/8 staff_space#; + +define_pixels (mens_block_rest_y, mens_half_block_rest_y, + pen_width, pen_height); + + +fet_beginchar ("Mensural maxima rest", "M3mensural"); + set_char_box (0, pen_width#, + mens_block_rest_y#, 2 mens_block_rest_y#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated slight_pen_rotation; + + draw (w / 2, -mens_block_rest_y) + -- (w / 2, 2 mens_block_rest_y); +fet_endchar; + + +fet_beginchar ("Mensural longa rest", "M2mensural"); + set_char_box (0, pen_width#, + mens_block_rest_y#, mens_block_rest_y#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated slight_pen_rotation; + + draw (w / 2, -mens_block_rest_y) + -- (w / 2, mens_block_rest_y); +fet_endchar; + + +fet_beginchar ("Mensural breve rest", "M1mensural"); + set_char_box (0, pen_width#, + 0, mens_block_rest_y#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated slight_pen_rotation; + + draw (w / 2, 0) + -- (w / 2, mens_block_rest_y); +fet_endchar; + + +fet_beginchar ("Mensural whole rest", "0mensural"); + set_char_box (0, pen_width#, + mens_half_block_rest_y#, 0); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated slight_pen_rotation; + + draw (w / 2, 0) + -- (w / 2, -mens_half_block_rest_y); +fet_endchar; + + +fet_beginchar ("Mensural half rest", "1mensural"); + set_char_box (0, pen_width#, + 0, mens_half_block_rest_y#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated slight_pen_rotation; + + draw (w / 2, 0) + -- (w / 2, mens_half_block_rest_y); +fet_endchar; + + +mensrestsize# = .8 staff_space#; + + +fet_beginchar ("Mensural 4th rest", "2mensural"); + set_char_box (0, mensrestsize#, + 0, mensrestsize#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated pen_rotation; + + lft x1 = 0; + y1 = 0; + lft x2 = 0; + top y2 = 5/8 h; + rt x3 = 1/5 w; + bot y3 = 6/8 h; + rt x4 = w; + bot y4 = 4/8 h; + + draw z1 + -- z2 + -- z3 + -- z4; + + labels (1, 2, 3, 4); +fet_endchar; + +% +% FIXME: The left sharp corner produces ugly results at lower resolutions. +% +fet_beginchar ("Mensural 8th rest", "3mensural"); + set_char_box (0, mensrestsize#, + 0, mensrestsize#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated pen_rotation; + + rt x1 = w; + y1 = 0; + rt x2 = w; + top y2 = 5/8 h; + lft x3 = 1/5 w; + bot y3 = 6/8 h; + lft x4 = 0; + bot y4 = 4/8 h; + + draw z1 + -- z2 + -- z3 + -- z4; + + labels (1, 2, 3, 4); +fet_endchar; + +% +% FIXME: So far, I have never seen a semifusa rest printed. Hence, +% the shape of this font character is currently pure invention. --jr +% +% +% FIXME: The left sharp corner produces ugly results at lower resolutions. +% +fet_beginchar ("Mensural 16th rest", "4mensural"); + set_char_box (0, mensrestsize#, + 0, staff_space#); + + pickup pencircle xscaled pen_width + yscaled pen_height + rotated pen_rotation; + + rt x1 = w; + y1 = 0; + rt x2 = w; + top y2 = 5.5/8 h; + lft x3 = 1/5 w; + bot y3 = 6.5/8 h; + lft x4 = 0; + bot y4 = 4.5/8 h; + rt x5 = w; + top y5 = 2.5/8 h; + lft x6 = 1/5 w; + bot y6 = 3.5/8 h; + lft x7 = 0; + bot y7 = 1.5/8 h; + + draw z1 + -- z2 + -- z3 + -- z4; + draw z5 + -- z6 + -- z7; + + labels (1, 2, 3, 4, 5, 6, 7); +fet_endchar; + + +fet_endgroup ("rests") diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-scripts.mf b/muse2/share/scoreglyphs/feta-original/parmesan-scripts.mf new file mode 100644 index 00000000..3a43a46a --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-scripts.mf @@ -0,0 +1,231 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-scripts.mf -- implement ancient script symbols +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 2002--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("scripts"); + +fet_beginchar ("ictus", "ictus"); + save ht, wd; + ht# = .35 staff_space#; + wd# = linethickness#; + + define_pixels (wd, ht); + + save ellipse, T; + path ellipse; + transform T; + + T := identity xscaled wd + yscaled blot_diameter; + pickup pencircle transformed T; + ellipse := fullcircle transformed T; + + set_char_box (wd# / 2, wd# / 2, ht# / 2, ht# / 2); + + x1 = 0; + top y1 = ht / 2; + x2 = 0; + bot y2 = -ht / 2; + + fill get_subpath (ellipse, up, down, z1) + -- get_subpath (ellipse, down, up, z2) + -- cycle; + + labels (1, 2); +fet_endchar; + + +def draw_accentus = + save thick, thin, ht, wd; + + thin# = 1 linethickness#; + thick# = 1.2 linethickness#; + ht# = .35 staff_space#; + wd# = .25 staff_space#; + + define_pixels (wd, ht, thin, thick); + + z1 = z2 = (-wd / 2 + thin / 2, -ht / 2 + thin / 2); + z3 = z4 = (wd / 2 - thick / 2, ht / 2 - thick / 2); + + penpos1 (thin, angle (z1 - z3)); + penpos2 (thin, angle (z1 - z3) + 90); + penpos3 (thick, angle (z3 - z1) + 90); + penpos4 (thick, angle (z3 - z1)); + + fill z1r + .. z2r + -- z3l + .. z4r + .. z3r + -- z2l + .. cycle; + + set_char_box (wd#/2, wd#/2, ht#/2, ht#/2); +enddef; + + +fet_beginchar ("accentus up", "uaccentus"); + draw_accentus; + penlabels (1, 2, 3, 4); +fet_endchar; + + +fet_beginchar ("accentus down", "daccentus"); + draw_accentus; + y_mirror_char; +fet_endchar; + + +def draw_half_circle (expr diam) = + save diameter, thick; + + diameter# = diam; + + define_pixels (diameter); + + thick = 0.6 linethickness; + + penpos1 (thick, 0); + penpos2 (thick, -90); + penpos3 (thick, -180); + + z1r = (diameter / 2, 0); + z2r = (0, -diameter / 2); + z3r = (-diameter / 2, 0); + + penstroke z1e{down} + .. z2e{left} + .. z3e{up}; +enddef; + + +fet_beginchar ("half circle", "usemicirculus"); + draw_half_circle (5/16 staff_space#); + + currentpicture := currentpicture yscaled -1; + + set_char_box (diameter# / 2, diameter# / 2, + 0, diameter# / 2); +fet_endchar; + + +fet_beginchar ("half circle", "dsemicirculus"); + draw_half_circle (5/16 staff_space#); + + set_char_box (diameter# / 2, diameter# / 2, + diameter# / 2, 0); + + penlabels (1, 2, 3); +fet_endchar; + + +fet_beginchar ("circle", "circulus"); + save diameter, thick; + + diameter# = 5/16 staff_space#; + + define_pixels (diameter); + + thick = 0.6 linethickness; + + fill fullcircle scaled diameter; + unfill fullcircle scaled (diameter - 2 thick); + + set_char_box (diameter# / 2, diameter# / 2, + diameter# / 2, diameter# / 2); +fet_endchar; + + +fet_beginchar ("augmentum", "augmentum"); + save diameter; + + diameter# = 0.25 staff_space#; + + define_pixels (diameter); + + pickup pencircle scaled diameter; + + drawdot (0, 0); + + set_char_box (diameter# / 2, diameter# / 2, + diameter# / 2, diameter# / 2); +fet_endchar; + + +def draw_signum_congruentiae = + set_char_box (0.50 staff_space# + 1.5 linethickness#, + 0.50 staff_space# + 1.5 linethickness#, + 2.5 linethickness#, + 2.00 staff_space# + 3.5 linethickness#); + + save ellipse, pat; + path ellipse, pat; + + ellipse := fullcircle xscaled 1.0 linethickness + yscaled 5.0 linethickness + rotated -35; + + z1 = (+0.50 staff_space, +2.00 staff_space); + z2 = (+0.00 staff_space, +2.00 staff_space); + z3 = (-0.50 staff_space, +1.50 staff_space); + z4 = (-0.25 staff_space, +1.00 staff_space); + z5 = (+0.10 staff_space, +0.80 staff_space); + z6 = (+0.00 staff_space, +0.00 staff_space); + + pat := z1{-1, +1} + .. z2 + .. z3 + .. z4 + .. z5 + .. z6; + + % we avoid cusps originally present in `draw pat' + fill get_subpath (ellipse, + -direction 0 of pat, direction 0 of pat, z1) + .. get_subpoint (ellipse, direction 1 of pat, z2) + {direction 1 of pat} + .. get_subpoint (ellipse, direction 2 of pat, z3) + {direction 2 of pat} + .. get_subpoint (ellipse, direction 3 of pat, z4) + {direction 3 of pat} + .. get_subpoint (ellipse, direction 4 of pat, z5) + {direction 4 of pat} + .. get_subpath (ellipse, + direction 4.8 of pat, -direction 5 of pat, z6) + .. get_subpoint (ellipse, -direction 4 of pat, z5) + {-direction 4 of pat} + .. get_subpoint (ellipse, -direction 3 of pat, z4) + {-direction 3 of pat} + .. get_subpoint (ellipse, -direction 2.5 of pat, point 2.5 of pat) + .. get_subpoint (ellipse, -direction 1 of pat, z2) + {-direction 1 of pat} + .. cycle; + + pickup pencircle scaled 3.0 linethickness; + + z7 = (-0.5 staff_space, +0.0 staff_space); + z8 = (+0.5 staff_space, +0.0 staff_space); + + drawdot z7; + drawdot z8; +enddef; + + +fet_beginchar ("signum congruentiae up", "usignumcongruentiae"); + draw_signum_congruentiae; + labels (1, 2, 3, 4, 5, 6, 7, 8); +fet_endchar; + + +fet_beginchar ("signum congruentiae down", "dsignumcongruentiae"); + draw_signum_congruentiae; + xy_mirror_char; +fet_endchar; + + +fet_endgroup ("scripts"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan-timesig.mf b/muse2/share/scoreglyphs/feta-original/parmesan-timesig.mf new file mode 100644 index 00000000..8d0ab9d4 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan-timesig.mf @@ -0,0 +1,395 @@ +% -%-Fundamental-%- -*-Metafont-*- +% parmesan-timesig.mf -- implement ancient time signatures +% +% source file of LilyPond's pretty-but-neat music font +% +% (c) 1998--2009 Mats Bengtsson <matsb@s3.kth.se>, +% Christian Mondrup <scancm@biobase.dk> +% (c) 2002--2009 Juergen Reuter <reuter@ipd.uka.de> +% + +fet_begingroup ("timesig"); + + +path threequartercircle; + +threequartercircle := halfcircle & quartercircle rotated 180; + +save mensural_Cdiameter, mensural_Cthickness, mensural_Chairpin; + +mensural_Cdiameter# := 3/2 staff_space#; +mensural_Cthickness# := 2 linethickness#; +mensural_Chairpin# := 0.5 linethickness#; + +define_pixels (mensural_Cdiameter, mensural_Cthickness, mensural_Chairpin); + + +%%%%%%%% +% +% +% +% MENSURAL NOTATION +% +% +% + +def draw_nail (expr bottom_left, top_right) = + save round; + + round = floor min (blot_diameter, + xpart (top_right-bottom_left), + ypart (top_right-bottom_left)); + + pickup pencircle scaled round; + + z2 + (round / 2, round / 2) = top_right + + (mensural_Cthickness / 2, 0); + z4 - (round / 2,round / 2) = bottom_left; + y3 = y2; + y4 = y1; + x2 = x1 + mensural_Cthickness / 2; + x2 - x1 = x4 - x3; + x5 = x1; + x6 = x4; + y5 = y6 = y2 - 2 mensural_Cthickness; + + fill bot z1{right} + .. rt z1{up} + -- rt z5{up} + .. rt z2 + .. top z2{left} + -- top z3{left} + .. lft z3 + .. lft z6{down} + -- lft z4{down} + .. bot z4{right} + -- cycle; + +% labels (1, 2, 3, 4, 5, 6); +enddef; + + +def mensural_timesig (expr verbose_name, internal_name, + full_circle, reverse_circle, slashed, dotted) = + fet_beginchar (verbose_name, internal_name); + if slashed: + set_char_box ( + 0, + mensural_Cdiameter# + mensural_Cthickness#, + .75 (mensural_Cdiameter# + mensural_Cthickness#), + .75 (mensural_Cdiameter# + mensural_Cthickness#)); + + if (full_circle or dotted): + draw_nail ((-mensural_Cthickness / 2, -d), + (mensural_Cthickness / 2, h)); + elseif reverse_circle: + draw_nail ((0, -d), (mensural_Cthickness, h)); + else: + draw_nail ((-mensural_Cthickness, -d), (0, h)); + fi; + else: + set_char_box ( + 0, + mensural_Cdiameter# + mensural_Cthickness#, + .5 (mensural_Cdiameter# + mensural_Cthickness#), + .5 (mensural_Cdiameter# + mensural_Cthickness#)); + fi; + + save ellipse, pat; + path ellipse, pat; + + ellipse := fullcircle xscaled mensural_Cthickness + yscaled mensural_Chairpin; + + save rot; + + if reverse_circle: + rot := 225; + else: + rot := 45; + fi; + + if full_circle: + pat := fullcircle scaled mensural_Cdiameter; + + fill get_subpoint (ellipse, + direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until length pat: + .. get_subpoint (ellipse, + direction i of pat, + point i of pat) + endfor + .. cycle; + unfill get_subpoint (ellipse, + -direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until length pat: + .. get_subpoint (ellipse, + -direction i of pat, + point i of pat) + endfor + .. cycle; + else: + pat := threequartercircle rotated rot + scaled mensural_Cdiameter; + + fill get_subpath (ellipse, + -direction 0 of pat, + direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until (length pat - 1): + .. get_subpoint (ellipse, + direction i of pat, + point i of pat) + endfor + .. get_subpath (ellipse, + direction infinity of pat, + -direction infinity of pat, + point infinity of pat) + for i = (length pat - 1) step -1 until 1: + .. get_subpoint (ellipse, + -direction i of pat, + point i of pat) + endfor + .. cycle; + fi; + + if dotted: + pickup pencircle scaled 4 linethickness; + drawdot (0, 0); + fi; + + currentpicture := currentpicture + shifted 0.5 (mensural_Cdiameter + + mensural_Cthickness, 0); + fet_endchar; +enddef; + + +%% tempus imperfectum cum prolatione imperfecta +mensural_timesig ("Mensural 4/4 meter", "mensural44", + false, false, false, false); + + +%% tempus imperfectum cum prolatione imperfecta proportio dupla +mensural_timesig ("Mensural 2/2 meter", "mensural22", + false, false, true, false); + + +%% tempus perfectum cum prolatione imperfecta +mensural_timesig ("Mensural 3/2 meter", "mensural32", + true, false, false, false); + + +%% tempus imperfectum cum prolatione perfecta +mensural_timesig ("Mensural 6/4 meter", "mensural64", + false, false, false, true); + + +%% tempus perfectum cum prolatione perfecta +mensural_timesig ("Mensural 9/4 meter", "mensural94", + true, false, false, true); + + +%% tempus perfectum cum prolatione imperfecta proportio dupla +mensural_timesig ("Mensural 3/4 meter", "mensural34", + true, false, true, false); + + +%% tempus imperfectum cum prolatione perfecta proportio dupla +mensural_timesig ("Mensural 6/8 meter", "mensural68", + false, false, true, true); + + +%% tempus perfectum cum prolatione perfecta proportio dupla +mensural_timesig ("Mensural 9/8 meter", "mensural98", + true, false, true, true); + + +%% tempus imperfectum cum prolatione imperfecta diminutio simplex +mensural_timesig ("Mensural 4/8 meter", "mensural48", + false, true, false, false); + + +%% tempus imperfectum cum prolatione perfecta diminutio simplex +mensural_timesig ("Mensural 6/8 meter", "mensural68alt", + false, true, false, true); + + +%% tempus imperfectum cum prolatione imperfecta diminutio duplex +mensural_timesig ("Mensural 2/4 meter", "mensural24", + false, true, true, false); + + +%%%%%%%% +% +% +% +% NEO-MENSURAL NOTATION +% +% +% + +save neomensural_Cdiameter, neomensural_Cthickness; + +neomensural_Cdiameter# := 3/2 staff_space#; +neomensural_Cthickness# := 2 linethickness#; + +define_pixels (neomensural_Cdiameter, neomensural_Cthickness); + + +def neomensural_timesig (expr verbose_name, internal_name, + full_circle, reverse_circle, slashed, dotted) = + fet_beginchar (verbose_name, internal_name); + set_char_box ( + 0, + neomensural_Cdiameter# + neomensural_Cthickness#, + .5 (neomensural_Cdiameter# + neomensural_Cthickness#), + .5 (neomensural_Cdiameter# + neomensural_Cthickness#)); + + if slashed: + pickup penrazor scaled neomensural_Cthickness; + + save t; + t := neomensural_Cthickness / 2; + + if (full_circle or dotted): + draw (0, -d + t) + -- (0, h - t); + elseif reverse_circle: + draw (t, -d + t) + -- (t, h - t); + else: + draw (-t, -d + t) + -- (-t, h - t); + fi; + fi; + + save ellipse, pat; + path ellipse, pat; + + ellipse := fullcircle scaled neomensural_Cthickness; + + save rot; + + if reverse_circle: + rot := 225; + else: + rot := 45; + fi; + + if full_circle: + pat := fullcircle scaled neomensural_Cdiameter; + + fill get_subpoint (ellipse, + direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until length pat: + .. get_subpoint (ellipse, + direction i of pat, + point i of pat) + endfor + .. cycle; + unfill get_subpoint (ellipse, + -direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until length pat: + .. get_subpoint (ellipse, + -direction i of pat, + point i of pat) + endfor + .. cycle; + else: + pat := threequartercircle rotated rot + scaled neomensural_Cdiameter; + + fill get_subpath (ellipse, + -direction 0 of pat, + direction 0 of pat, + point 0 of pat) + for i = 1 step 1 until (length pat - 1): + .. get_subpoint (ellipse, + direction i of pat, + point i of pat) + endfor + .. get_subpath (ellipse, + direction infinity of pat, + -direction infinity of pat, + point infinity of pat) + for i = (length pat - 1) step -1 until 1: + .. get_subpoint (ellipse, + -direction i of pat, + point i of pat) + endfor + .. cycle; + fi; + + if dotted: + pickup pencircle scaled 4 linethickness; + drawdot (0, 0); + fi; + + currentpicture := currentpicture + shifted 0.5 (neomensural_Cdiameter + + neomensural_Cthickness, 0); + fet_endchar; +enddef; + + +%% tempus imperfectum cum prolatione imperfecta +neomensural_timesig ("Mensural 4/4 meter", "neomensural44", + false, false, false, false); + + +%% tempus imperfectum cum prolatione imperfecta proportio dupla +neomensural_timesig ("Mensural 2/2 meter", "neomensural22", + false, false, true, false); + + +%% tempus perfectum cum prolatione imperfecta +neomensural_timesig ("Mensural 3/2 meter", "neomensural32", + true, false, false, false); + + +%% tempus imperfectum cum prolatione perfecta +neomensural_timesig ("Mensural 6/4 meter", "neomensural64", + false, false, false, true); + + +%% tempus perfectum cum prolatione perfecta +neomensural_timesig ("Mensural 9/4 meter", "neomensural94", + true, false, false, true); + + +%% tempus perfectum cum prolatione imperfecta proportio dupla +neomensural_timesig ("Mensural 3/4 meter", "neomensural34", + true, false, true, false); + + +%% tempus imperfectum cum prolatione perfecta proportio dupla +neomensural_timesig ("Mensural 6/8 meter", "neomensural68", + false, false, true, true); + + +%% tempus perfectum cum prolatione perfecta proportio dupla +neomensural_timesig ("Mensural 9/8 meter", "neomensural98", + true, false, true, true); + + +%% tempus imperfectum cum prolatione imperfecta diminutio simplex +neomensural_timesig ("Mensural 4/8 meter", "neomensural48", + false, true, false, false); + + +%% tempus imperfectum cum prolatione perfecta diminutio simplex +neomensural_timesig ("Mensural 6/8 meter", "neomensural68alt", + false, true, false, true); + + +%% tempus imperfectum cum prolatione imperfecta diminutio duplex +neomensural_timesig ("Mensural 2/4 meter", "neomensural24", + false, true, true, false); + + +fet_endgroup ("timesig"); diff --git a/muse2/share/scoreglyphs/feta-original/parmesan11.mf b/muse2/share/scoreglyphs/feta-original/parmesan11.mf new file mode 100644 index 00000000..27ba3414 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan11.mf @@ -0,0 +1,13 @@ +% parmesan11.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 11.22; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan13.mf b/muse2/share/scoreglyphs/feta-original/parmesan13.mf new file mode 100644 index 00000000..905da48d --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan13.mf @@ -0,0 +1,14 @@ +% parmesan13.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 12.60; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan14.mf b/muse2/share/scoreglyphs/feta-original/parmesan14.mf new file mode 100644 index 00000000..6357337b --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan14.mf @@ -0,0 +1,14 @@ +% parmesan14.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 14.14; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan16.mf b/muse2/share/scoreglyphs/feta-original/parmesan16.mf new file mode 100644 index 00000000..19b05167 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan16.mf @@ -0,0 +1,14 @@ +% parmesan16.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 15.87; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan18.mf b/muse2/share/scoreglyphs/feta-original/parmesan18.mf new file mode 100644 index 00000000..8c285070 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan18.mf @@ -0,0 +1,14 @@ +% parmesan18.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 17.82; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan20.mf b/muse2/share/scoreglyphs/feta-original/parmesan20.mf new file mode 100644 index 00000000..d14251ed --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan20.mf @@ -0,0 +1,14 @@ +% parmesan20.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 20; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan23.mf b/muse2/share/scoreglyphs/feta-original/parmesan23.mf new file mode 100644 index 00000000..39b64373 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan23.mf @@ -0,0 +1,14 @@ +% parmesan23.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 22.45; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/feta-original/parmesan26.mf b/muse2/share/scoreglyphs/feta-original/parmesan26.mf new file mode 100644 index 00000000..1be6fb51 --- /dev/null +++ b/muse2/share/scoreglyphs/feta-original/parmesan26.mf @@ -0,0 +1,14 @@ +% parmesan26.mf +% part of LilyPond's pretty-but-neat music font + +design_size := 25.20; + +input feta-autometric; + +test := 0; + +input parmesan-generic; + + +end. + diff --git a/muse2/share/scoreglyphs/flags16d.png b/muse2/share/scoreglyphs/flags16d.png Binary files differnew file mode 100644 index 00000000..dbffcdee --- /dev/null +++ b/muse2/share/scoreglyphs/flags16d.png diff --git a/muse2/share/scoreglyphs/flags16u.png b/muse2/share/scoreglyphs/flags16u.png Binary files differnew file mode 100644 index 00000000..4278b260 --- /dev/null +++ b/muse2/share/scoreglyphs/flags16u.png diff --git a/muse2/share/scoreglyphs/flags32d.png b/muse2/share/scoreglyphs/flags32d.png Binary files differnew file mode 100644 index 00000000..7aedf14b --- /dev/null +++ b/muse2/share/scoreglyphs/flags32d.png diff --git a/muse2/share/scoreglyphs/flags32u.png b/muse2/share/scoreglyphs/flags32u.png Binary files differnew file mode 100644 index 00000000..ddcee1c2 --- /dev/null +++ b/muse2/share/scoreglyphs/flags32u.png diff --git a/muse2/share/scoreglyphs/flags64d.png b/muse2/share/scoreglyphs/flags64d.png Binary files differnew file mode 100644 index 00000000..30c622e0 --- /dev/null +++ b/muse2/share/scoreglyphs/flags64d.png diff --git a/muse2/share/scoreglyphs/flags64u.png b/muse2/share/scoreglyphs/flags64u.png Binary files differnew file mode 100644 index 00000000..5e1a099f --- /dev/null +++ b/muse2/share/scoreglyphs/flags64u.png diff --git a/muse2/share/scoreglyphs/flags8d.png b/muse2/share/scoreglyphs/flags8d.png Binary files differnew file mode 100644 index 00000000..664ee6b5 --- /dev/null +++ b/muse2/share/scoreglyphs/flags8d.png diff --git a/muse2/share/scoreglyphs/flags8u.png b/muse2/share/scoreglyphs/flags8u.png Binary files differnew file mode 100644 index 00000000..f80a9799 --- /dev/null +++ b/muse2/share/scoreglyphs/flags8u.png diff --git a/muse2/share/scoreglyphs/half.png b/muse2/share/scoreglyphs/half.png Binary files differnew file mode 100644 index 00000000..50be5da9 --- /dev/null +++ b/muse2/share/scoreglyphs/half.png diff --git a/muse2/share/scoreglyphs/quarter.png b/muse2/share/scoreglyphs/quarter.png Binary files differnew file mode 100644 index 00000000..f773f824 --- /dev/null +++ b/muse2/share/scoreglyphs/quarter.png diff --git a/muse2/share/scoreglyphs/rest1.png b/muse2/share/scoreglyphs/rest1.png Binary files differnew file mode 100644 index 00000000..3f0df51b --- /dev/null +++ b/muse2/share/scoreglyphs/rest1.png diff --git a/muse2/share/scoreglyphs/rest16.png b/muse2/share/scoreglyphs/rest16.png Binary files differnew file mode 100644 index 00000000..42fc656d --- /dev/null +++ b/muse2/share/scoreglyphs/rest16.png diff --git a/muse2/share/scoreglyphs/rest2.png b/muse2/share/scoreglyphs/rest2.png Binary files differnew file mode 100644 index 00000000..0f4497f7 --- /dev/null +++ b/muse2/share/scoreglyphs/rest2.png diff --git a/muse2/share/scoreglyphs/rest4.png b/muse2/share/scoreglyphs/rest4.png Binary files differnew file mode 100644 index 00000000..c229426d --- /dev/null +++ b/muse2/share/scoreglyphs/rest4.png diff --git a/muse2/share/scoreglyphs/rest8.png b/muse2/share/scoreglyphs/rest8.png Binary files differnew file mode 100644 index 00000000..b3289706 --- /dev/null +++ b/muse2/share/scoreglyphs/rest8.png diff --git a/muse2/share/scoreglyphs/whole.png b/muse2/share/scoreglyphs/whole.png Binary files differnew file mode 100644 index 00000000..eb8b4b7f --- /dev/null +++ b/muse2/share/scoreglyphs/whole.png |