From f04243aecfb95c3f427ab7d7a43f3a884972dc4b Mon Sep 17 00:00:00 2001 From: Paul Overell Date: Sat, 22 Jul 2023 12:15:35 +0100 Subject: [PATCH 1/3] GLT vertical positioning and @notationsubtype --- include/vrv/note.h | 3 ++- include/vrv/staffdef.h | 3 ++- include/vrv/tabdursym.h | 2 +- include/vrv/tuning.h | 8 ++++-- src/calcalignmentpitchposfunctor.cpp | 4 ++- src/iomei.cpp | 4 +++ src/note.cpp | 39 ++++++++++++++++++++-------- src/staffdef.cpp | 3 +++ src/tabdursym.cpp | 5 +++- src/tuning.cpp | 15 +++++++++-- src/view_tab.cpp | 39 +++++++++++++++++++++------- 11 files changed, 96 insertions(+), 29 deletions(-) diff --git a/include/vrv/note.h b/include/vrv/note.h index d44bc06d88b..af51ac7e17c 100644 --- a/include/vrv/note.h +++ b/include/vrv/note.h @@ -162,7 +162,8 @@ class Note : public LayerElement, * @name Return the smufl string to use for a note give the notation type */ ///@{ - std::u32string GetTabFretString(data_NOTATIONTYPE notationType, bool &overline) const; + std::u32string GetTabFretString( + data_NOTATIONTYPE notationType, const std::string ¬ationSubtype, int &overline, int &strike) const; ///@} /** diff --git a/include/vrv/staffdef.h b/include/vrv/staffdef.h index 7e779f3df01..b59d303483f 100644 --- a/include/vrv/staffdef.h +++ b/include/vrv/staffdef.h @@ -32,7 +32,8 @@ class StaffDef : public ScoreDefElement, public AttStaffDefLog, public AttStaffDefVis, public AttTimeBase, - public AttTransposition { + public AttTransposition, + public AttVerticalAlign { public: /** * @name Constructors, destructors, and other standard methods diff --git a/include/vrv/tabdursym.h b/include/vrv/tabdursym.h index 87e39ab2188..baa44140519 100644 --- a/include/vrv/tabdursym.h +++ b/include/vrv/tabdursym.h @@ -21,7 +21,7 @@ namespace vrv { /** * This class models the MEI element. */ -class TabDurSym : public LayerElement, public StemmedDrawingInterface, public AttNNumberLike { +class TabDurSym : public LayerElement, public StemmedDrawingInterface, public AttNNumberLike, public AttStaffLoc { public: /** * @name Constructors, destructors, and other standard methods diff --git a/include/vrv/tuning.h b/include/vrv/tuning.h index a45f30ae14f..3615eb0a725 100644 --- a/include/vrv/tuning.h +++ b/include/vrv/tuning.h @@ -42,16 +42,20 @@ class Tuning : public Object, public AttCourseLog { /** * Return the line for a note according to tablature type. * Guitar, french and italian tablature: the line is based on the course. - * German tablature: the line is based on the note's index in the note list. + * German tablature: the line is based on the note's index in the note list + * or by explicit @loc. * * @param[in] course * @param[in] notationType * @param[in] lines * @param[in] listSize * @param[in] index - 0 based from the bottom of the chord + * @param[in] loc - German tablature: note@loc if specified, 0 at the bottom + * @param[in] topAlign - German tablature: true => align at the top, false => align at the bottom * @return position in staff half lines */ - int CalcPitchPos(int course, data_NOTATIONTYPE notationType, int lines, int listSize, int index) const; + int CalcPitchPos( + int course, data_NOTATIONTYPE notationType, int lines, int listSize, int index, int loc, bool topAlign) const; /** * Calclate the MIDI pitch number for course/fret diff --git a/src/calcalignmentpitchposfunctor.cpp b/src/calcalignmentpitchposfunctor.cpp index 2779484c12a..fd2bb60401b 100644 --- a/src/calcalignmentpitchposfunctor.cpp +++ b/src/calcalignmentpitchposfunctor.cpp @@ -92,8 +92,10 @@ FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerE TabGrp *tabGrp = note->IsTabGrpNote(); if (tabGrp) { assert(staffY->m_drawingTuning); + assert(staffY->m_drawingStaffDef); loc = staffY->m_drawingTuning->CalcPitchPos(note->GetTabCourse(), staffY->m_drawingNotationType, - staffY->m_drawingLines, tabGrp->GetListSize(tabGrp), tabGrp->GetListIndex(note)); + staffY->m_drawingLines, tabGrp->GetListSize(tabGrp), tabGrp->GetListIndex(note), note->GetLoc(), + staffY->m_drawingStaffDef->GetValign() != VERTICALALIGNMENT_bottom); } else if ((note->HasPname() && note->HasOct()) || note->HasLoc()) { loc = PitchInterface::CalcLoc(note, layerY, layerElementY); diff --git a/src/iomei.cpp b/src/iomei.cpp index b5bdbf9f706..ff785bfbcc5 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -1807,6 +1807,7 @@ void MEIOutput::WriteStaffDef(pugi::xml_node currentNode, StaffDef *staffDef) staffDef->WriteStaffDefVis(currentNode); staffDef->WriteTimeBase(currentNode); staffDef->WriteTransposition(currentNode); + staffDef->WriteVerticalAlign(currentNode); } void MEIOutput::WriteInstrDef(pugi::xml_node currentNode, InstrDef *instrDef) @@ -2774,6 +2775,7 @@ void MEIOutput::WriteTabDurSym(pugi::xml_node currentNode, TabDurSym *tabDurSym) this->WriteLayerElement(currentNode, tabDurSym); tabDurSym->WriteNNumberLike(currentNode); + tabDurSym->WriteStaffLoc(currentNode); } void MEIOutput::WriteTabGrp(pugi::xml_node currentNode, TabGrp *tabGrp) @@ -5073,6 +5075,7 @@ bool MEIInput::ReadStaffDef(Object *parent, pugi::xml_node staffDef) vrvStaffDef->ReadStaffDefVis(staffDef); vrvStaffDef->ReadTimeBase(staffDef); vrvStaffDef->ReadTransposition(staffDef); + vrvStaffDef->ReadVerticalAlign(staffDef); if (!vrvStaffDef->HasN()) { LogWarning("No @n on might yield unpredictable results"); @@ -6922,6 +6925,7 @@ bool MEIInput::ReadTabDurSym(Object *parent, pugi::xml_node tabRhyhtm) this->ReadLayerElement(tabRhyhtm, vrvTabDurSym); vrvTabDurSym->ReadNNumberLike(tabRhyhtm); + vrvTabDurSym->ReadStaffLoc(tabRhyhtm); parent->AddChild(vrvTabDurSym); this->ReadUnsupportedAttr(tabRhyhtm, vrvTabDurSym); diff --git a/src/note.cpp b/src/note.cpp index 6b60bfb837d..013b173482d 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -267,9 +267,11 @@ const TabGrp *Note::IsTabGrpNote() const return vrv_cast(this->GetFirstAncestor(TABGRP, MAX_TABGRP_DEPTH)); } -std::u32string Note::GetTabFretString(data_NOTATIONTYPE notationType, bool &overline) const +std::u32string Note::GetTabFretString( + data_NOTATIONTYPE notationType, const std::string ¬ationSubtype, int &overline, int &strike) const { - overline = false; + overline = 0; + strike = 0; if (notationType == NOTATIONTYPE_tab_lute_italian) { std::u32string fretStr; @@ -350,23 +352,38 @@ std::u32string Note::GetTabFretString(data_NOTATIONTYPE notationType, bool &over // // However, some glyphs are missing: // - // Digit 1 with an oblique stroke for the open 6th course. + // Digit 1 with a strike through for the open 6th course. + // Digit 1 with two strike throughs for the open 7th course. + // Digit 1 with three strike throughs for the open 8th course. // "et" for 2nd course 5th fret. // "con" for 1st course 5th fret. // Gothic font digits 1-5 for the open courses <= 5. // Second lowercase alphabet with an overline used for courses <= 5 frets 6 to 10. // // To overcome these omissions I've substituted missing glyphs from other - // parts of the SMuFL collection. Overlines are drawn separately. + // parts of the SMuFL collection. Overlines and strike throughs are drawn separately. - if (course == 6 && fret >= 0 && fret <= 13) { - if (fret == 0) { - fretStr = SMUFL_E595_ornamentLeftVerticalStrokeWithCross; // substitute for 1 with oblique stroke - } - else { + if (course >= 6 && fret >= 0 && fret <= 13) { + // TODO more GLT subtypes needed, is this subtype too specific? + if (notationSubtype == "judenkunig_1523") { + // A B C D ... // The German tablature uppercase letters A-N are contiguous, correctly omitting J static_assert(SMUFL_EC23_luteGermanNUpper == SMUFL_EC17_luteGermanAUpper + 13 - 1); - fretStr = SMUFL_EC17_luteGermanAUpper + fret - 1; + fretStr = SMUFL_EC17_luteGermanAUpper + fret; + overline = course - 6; // 6 course 0 overline, 7 course 1 overline, ... + } + else { + // + A B C D ... + if (fret == 0) { + fretStr = SMUFL_EA51_figbass1; // substitute for 1 with oblique stroke + strike = course - 5; // 6 course 1 strike, 7 course 2 strikes, ... + } + else { + // The German tablature uppercase letters A-N are contiguous, correctly omitting J + static_assert(SMUFL_EC23_luteGermanNUpper == SMUFL_EC17_luteGermanAUpper + 13 - 1); + fretStr = SMUFL_EC17_luteGermanAUpper + fret - 1; + overline = course - 6; // 6 course 0 overline, 7 course 1 overline, ... + } } } else if (course >= 1 && course <= 5 && fret == 0) { @@ -394,7 +411,7 @@ std::u32string Note::GetTabFretString(data_NOTATIONTYPE notationType, bool &over } // second alphabet needs an overline - overline = (fret >= 6); + overline = (fret >= 6) ? 1 : 0; } return fretStr; } diff --git a/src/staffdef.cpp b/src/staffdef.cpp index 5a86e2a6c48..5d55f3c8f80 100644 --- a/src/staffdef.cpp +++ b/src/staffdef.cpp @@ -42,6 +42,7 @@ StaffDef::StaffDef() , AttStaffDefVis() , AttTimeBase() , AttTransposition() + , AttVerticalAlign() { this->RegisterAttClass(ATT_DISTANCES); this->RegisterAttClass(ATT_LABELLED); @@ -52,6 +53,7 @@ StaffDef::StaffDef() this->RegisterAttClass(ATT_STAFFDEFVIS); this->RegisterAttClass(ATT_TIMEBASE); this->RegisterAttClass(ATT_TRANSPOSITION); + this->RegisterAttClass(ATT_VERTICALALIGN); this->Reset(); } @@ -71,6 +73,7 @@ void StaffDef::Reset() this->ResetStaffDefVis(); this->ResetTimeBase(); this->ResetTransposition(); + this->ResetVerticalAlign(); m_drawingVisibility = OPTIMIZATION_NONE; } diff --git a/src/tabdursym.cpp b/src/tabdursym.cpp index 1ac5721f437..2bb64949d1c 100644 --- a/src/tabdursym.cpp +++ b/src/tabdursym.cpp @@ -31,9 +31,11 @@ namespace vrv { static const ClassRegistrar s_factory("tabDurSym", TABDURSYM); -TabDurSym::TabDurSym() : LayerElement(TABDURSYM, "tabdursym-"), StemmedDrawingInterface(), AttNNumberLike() +TabDurSym::TabDurSym() + : LayerElement(TABDURSYM, "tabdursym-"), StemmedDrawingInterface(), AttNNumberLike(), AttStaffLoc() { this->RegisterAttClass(ATT_NNUMBERLIKE); + this->RegisterAttClass(ATT_STAFFLOC); this->Reset(); } @@ -45,6 +47,7 @@ void TabDurSym::Reset() LayerElement::Reset(); StemmedDrawingInterface::Reset(); this->ResetNNumberLike(); + this->ResetStaffLoc(); } bool TabDurSym::IsSupportedChild(Object *child) diff --git a/src/tuning.cpp b/src/tuning.cpp index 43b3d57fd8f..c7f71fa3f3d 100644 --- a/src/tuning.cpp +++ b/src/tuning.cpp @@ -56,14 +56,25 @@ bool Tuning::IsSupportedChild(Object *child) return true; } -int Tuning::CalcPitchPos(int course, data_NOTATIONTYPE notationType, int lines, int listSize, int index) const +int Tuning::CalcPitchPos( + int course, data_NOTATIONTYPE notationType, int lines, int listSize, int index, int loc, bool topAlign) const { switch (notationType) { case NOTATIONTYPE_tab_lute_french: // all courses >= 7 are positioned above line 0 return (lines - std::min(course, 7)) * 2 + 1; // above the line case NOTATIONTYPE_tab_lute_italian: return (course - 1) * 2; - case NOTATIONTYPE_tab_lute_german: return (lines - (listSize - index)) * 2; + case NOTATIONTYPE_tab_lute_german: + if (loc != MEI_UNSET) { + return loc; + } + else if (topAlign) { + return (lines - (listSize - index)) * 2; + } + else { + // bottom align + return index * 2; + } case NOTATIONTYPE_tab_guitar: [[fallthrough]]; default: return abs(course - lines) * 2; } diff --git a/src/view_tab.cpp b/src/view_tab.cpp index f72aeb4f78b..d82377d1d2f 100644 --- a/src/view_tab.cpp +++ b/src/view_tab.cpp @@ -22,6 +22,7 @@ #include "rend.h" #include "smufl.h" #include "staff.h" +#include "staffdef.h" #include "stem.h" #include "system.h" #include "tabdursym.h" @@ -105,11 +106,13 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S int glyphSize = staff->GetDrawingStaffNotationSize(); bool drawingCueSize = false; - bool overline = false; + int overline = 0; + int strike = 0; if (staff->m_drawingNotationType == NOTATIONTYPE_tab_guitar) { - std::u32string fret = note->GetTabFretString(staff->m_drawingNotationType, overline); + std::u32string fret = note->GetTabFretString( + staff->m_drawingNotationType, staff->m_drawingStaffDef->GetNotationsubtype(), overline, strike); FontInfo fretTxt; if (!dc->UseGlobalStyling()) { @@ -135,7 +138,8 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S } else { - std::u32string fret = note->GetTabFretString(staff->m_drawingNotationType, overline); + std::u32string fret = note->GetTabFretString( + staff->m_drawingNotationType, staff->m_drawingStaffDef->GetNotationsubtype(), overline, strike); // Center for italian tablature if (staff->IsTabLuteItalian()) { y -= (m_doc->GetGlyphHeight(SMUFL_EBE0_luteItalianFret0, glyphSize, drawingCueSize) / 2); @@ -153,8 +157,8 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S dc->SetFont(m_doc->GetDrawingSmuflFont(glyphSize, false)); this->DrawSmuflString(dc, x, y, fret, HORIZONTALALIGNMENT_center, glyphSize); - // Add overline if required - if (overline && !fret.empty()) { + // Add overlines or strikethoughs if required + if ((overline > 0 || strike > 0) && !fret.empty()) { const int lineThickness = m_options->m_lyricLineThickness.GetValue() * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); const int widthFront = m_doc->GetGlyphWidth(fret.front(), glyphSize, drawingCueSize); @@ -165,13 +169,24 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S const int x1 = x - widthFront / 2; const int x2 = x + extend.m_width - widthBack * 3 / 10; // trim right hand overhang on last character - const int y1 = y + extend.m_ascent + lineThickness; - const int y2 = y1; - dc->SetPen(m_currentColor, lineThickness, AxSOLID); dc->SetBrush(m_currentColor, AxSOLID); - dc->DrawLine(ToDeviceContextX(x1), ToDeviceContextY(y1), ToDeviceContextX(x2), ToDeviceContextY(y2)); + // overlines + int y1 = y + extend.m_ascent + lineThickness; + + for (int i = 0; i < overline; ++i) { + dc->DrawLine(ToDeviceContextX(x1), ToDeviceContextY(y1), ToDeviceContextX(x2), ToDeviceContextY(y1)); + y1 += 2 * lineThickness; + } + + // strikethroughs + y1 = y + extend.m_ascent / 2 - (strike - 1) * lineThickness; + + for (int i = 0; i < strike; ++i) { + dc->DrawLine(ToDeviceContextX(x1), ToDeviceContextY(y1), ToDeviceContextX(x2), ToDeviceContextY(y1)); + y1 += 2 * lineThickness; + } dc->ResetPen(); dc->ResetBrush(); @@ -200,6 +215,12 @@ void View::DrawTabDurSym(DeviceContext *dc, LayerElement *element, Layer *layer, dc->StartGraphic(tabDurSym, "", tabDurSym->GetID()); + if (tabDurSym->HasLoc()) { + const int yRel = ((staff->m_drawingLines - 1) * 2 - tabDurSym->GetLoc()) + * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + tabDurSym->SetDrawingYRel(-yRel); + } + int x = element->GetDrawingX(); int y = element->GetDrawingY(); From 7a58c928097897f5d7085dd8fa6fafb33b79d361 Mon Sep 17 00:00:00 2001 From: Paul Overell Date: Wed, 6 Sep 2023 11:49:23 +0100 Subject: [PATCH 2/3] Changed I/F for tabGrp::GetListSize --- src/calcalignmentpitchposfunctor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calcalignmentpitchposfunctor.cpp b/src/calcalignmentpitchposfunctor.cpp index 769e3e20306..6779ddac1c1 100644 --- a/src/calcalignmentpitchposfunctor.cpp +++ b/src/calcalignmentpitchposfunctor.cpp @@ -94,7 +94,7 @@ FunctorCode CalcAlignmentPitchPosFunctor::VisitLayerElement(LayerElement *layerE assert(staffY->m_drawingTuning); assert(staffY->m_drawingStaffDef); loc = staffY->m_drawingTuning->CalcPitchPos(note->GetTabCourse(), staffY->m_drawingNotationType, - staffY->m_drawingLines, tabGrp->GetListSize(tabGrp), tabGrp->GetListIndex(note), note->GetLoc(), + staffY->m_drawingLines, tabGrp->GetListSize(), tabGrp->GetListIndex(note), note->GetLoc(), staffY->m_drawingStaffDef->GetValign() != VERTICALALIGNMENT_bottom); } else if ((note->HasPname() && note->HasOct()) || note->HasLoc()) { From 51437a870334b3fe535a1af7d8672c40208d6646 Mon Sep 17 00:00:00 2001 From: Paul Overell Date: Tue, 23 Jan 2024 14:05:57 +0000 Subject: [PATCH 3/3] Remove @notationsubtype for German Lute Tablature --- include/vrv/note.h | 3 +-- src/note.cpp | 35 ++++++++++++++--------------------- src/view_tab.cpp | 6 ++---- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/include/vrv/note.h b/include/vrv/note.h index af51ac7e17c..cbeae02cb40 100644 --- a/include/vrv/note.h +++ b/include/vrv/note.h @@ -162,8 +162,7 @@ class Note : public LayerElement, * @name Return the smufl string to use for a note give the notation type */ ///@{ - std::u32string GetTabFretString( - data_NOTATIONTYPE notationType, const std::string ¬ationSubtype, int &overline, int &strike) const; + std::u32string GetTabFretString(data_NOTATIONTYPE notationType, int &overline, int &strike) const; ///@} /** diff --git a/src/note.cpp b/src/note.cpp index 3a1ca811a43..a9893e0f6e1 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -267,8 +267,7 @@ const TabGrp *Note::IsTabGrpNote() const return vrv_cast(this->GetFirstAncestor(TABGRP, MAX_TABGRP_DEPTH)); } -std::u32string Note::GetTabFretString( - data_NOTATIONTYPE notationType, const std::string ¬ationSubtype, int &overline, int &strike) const +std::u32string Note::GetTabFretString(data_NOTATIONTYPE notationType, int &overline, int &strike) const { overline = 0; strike = 0; @@ -345,8 +344,8 @@ std::u32string Note::GetTabFretString( const int fret = this->GetTabFret(); const int course = this->GetTabCourse(); - // SMuFL has glyphs for German lute tablature following Hans Newsidler's notation - // for the 6th course. + // SMuFL has glyphs for German lute tablature following Hans and Melchior Newsidler's notation + // for the >= 6th courses. // "German Renaissance lute tablature (U+EC00–U+EC2F)" // https://w3c.github.io/smufl/latest/tables/german-renaissance-lute-tablature.html // @@ -364,27 +363,17 @@ std::u32string Note::GetTabFretString( // parts of the SMuFL collection. Overlines and strike throughs are drawn separately. if (course >= 6 && fret >= 0 && fret <= 13) { - // TODO more GLT subtypes needed, is this subtype too specific? - if (notationSubtype == "judenkunig_1523") { - // A B C D ... + // + A B C D ... + if (fret == 0) { + fretStr = SMUFL_EA51_figbass1; // substitute for 1 with oblique stroke + strike = course - 5; // 6 course 1 strike, 7 course 2 strikes, ... + } + else { // The German tablature uppercase letters A-N are contiguous, correctly omitting J static_assert(SMUFL_EC23_luteGermanNUpper == SMUFL_EC17_luteGermanAUpper + 13 - 1); - fretStr = SMUFL_EC17_luteGermanAUpper + fret; + fretStr = SMUFL_EC17_luteGermanAUpper + fret - 1; overline = course - 6; // 6 course 0 overline, 7 course 1 overline, ... } - else { - // + A B C D ... - if (fret == 0) { - fretStr = SMUFL_EA51_figbass1; // substitute for 1 with oblique stroke - strike = course - 5; // 6 course 1 strike, 7 course 2 strikes, ... - } - else { - // The German tablature uppercase letters A-N are contiguous, correctly omitting J - static_assert(SMUFL_EC23_luteGermanNUpper == SMUFL_EC17_luteGermanAUpper + 13 - 1); - fretStr = SMUFL_EC17_luteGermanAUpper + fret - 1; - overline = course - 6; // 6 course 0 overline, 7 course 1 overline, ... - } - } } else if (course >= 1 && course <= 5 && fret == 0) { // Substitute for gothic digits @@ -396,9 +385,13 @@ std::u32string Note::GetTabFretString( const int firstAlphabetFret = fret <= 5 ? fret : fret - 5; // map second alphabet to first if (course == 2 && firstAlphabetFret == 5) { + // TODO replace with U+EC24, luteGermanEt when available + // https://github.com/w3c/smufl/issues/274 fretStr = SMUFL_EA5F_figbass7Raised2; // substitute for "et" } else if (course == 1 && firstAlphabetFret == 5) { + // TODO replace with U+EC25, luteGermanCon when available + // https://github.com/w3c/smufl/issues/274 fretStr = SMUFL_EA61_figbass9; // substitute for "con" } else { diff --git a/src/view_tab.cpp b/src/view_tab.cpp index d82377d1d2f..71246755554 100644 --- a/src/view_tab.cpp +++ b/src/view_tab.cpp @@ -111,8 +111,7 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S if (staff->m_drawingNotationType == NOTATIONTYPE_tab_guitar) { - std::u32string fret = note->GetTabFretString( - staff->m_drawingNotationType, staff->m_drawingStaffDef->GetNotationsubtype(), overline, strike); + std::u32string fret = note->GetTabFretString(staff->m_drawingNotationType, overline, strike); FontInfo fretTxt; if (!dc->UseGlobalStyling()) { @@ -138,8 +137,7 @@ void View::DrawTabNote(DeviceContext *dc, LayerElement *element, Layer *layer, S } else { - std::u32string fret = note->GetTabFretString( - staff->m_drawingNotationType, staff->m_drawingStaffDef->GetNotationsubtype(), overline, strike); + std::u32string fret = note->GetTabFretString(staff->m_drawingNotationType, overline, strike); // Center for italian tablature if (staff->IsTabLuteItalian()) { y -= (m_doc->GetGlyphHeight(SMUFL_EBE0_luteItalianFret0, glyphSize, drawingCueSize) / 2);