From 103167e0ad1ef61394050056ae90f50d1acf9961 Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Fri, 25 Jul 2025 08:47:02 -0500 Subject: [PATCH 1/2] Sync mss export changes in denigma utility --- src/document_options_to_musescore.lua | 70 +++++++++++++++++++++++---- src/library/score.lua | 27 +++++++++++ 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/document_options_to_musescore.lua b/src/document_options_to_musescore.lua index ba878e47..bdf53042 100644 --- a/src/document_options_to_musescore.lua +++ b/src/document_options_to_musescore.lua @@ -58,6 +58,7 @@ local mixin = require("library.mixin") local enigma_string = require("library.enigma_string") local utils = require("library.utils") local client = require("library.client") +local score = require("library.score") do_folder = do_folder or false @@ -119,6 +120,7 @@ local mmrest_prefs local tie_prefs local tuplet_prefs local text_exps +local music_font_name function open_current_prefs() local font_prefs = finale.FCFontPrefs() @@ -156,6 +158,25 @@ function open_current_prefs() tuplet_prefs:Load(1) text_exps = finale.FCTextExpressionDefs() text_exps:LoadAll() + music_font_name = default_music_font.Name -- piece of the rock + if default_music_font.IsSMuFLFont then + music_font_name = default_music_font.Name -- duplicate assignment avoids warning + elseif music_font_name == "Broadway Copyist" then + music_font_name = "Finale Broadway" + elseif music_font_name == "Engraver" then + music_font_name = "Finale Engraver" + elseif music_font_name == "Jazz" then + music_font_name = "Finale Jazz" + elseif music_font_name == "Maestro" + or music_font_name == "Pmusic" + or music_font_name == "Sonata" then + music_font_name = "Finale Maestro" + elseif music_font_name == "Petrucci" then + music_font_name = "Finale Legacy" + -- add more elseif blocks if needed + else + music_font_name = nil + end end function set_element_text(style_element, name, value) @@ -282,9 +303,26 @@ function write_page_prefs(style_element) local page_percent = page_prefs.PageScaling / 100 local staff_percent = (page_prefs.SystemStaffHeight / (EVPU_PER_SPACE * 4 * 16)) * (page_prefs.SystemScaling / 100) set_element_text(style_element, "spatium", (EVPU_PER_SPACE * staff_percent * page_percent) / EVPU_PER_MM) - if default_music_font.IsSMuFLFont then - set_element_text(style_element, "musicalSymbolFont", default_music_font.Name) - set_element_text(style_element, "musicalTextFont", default_music_font.Name .. " Text") + local first_system = finale.FCStaffSystem() + if first_system:LoadFirst() then + local min_size = 100 + if first_system.UseStaffResize then + local system_staves = finale.FCSystemStaves() + system_staves.LoadAllForItem(first_system.ItemNo) + for system_staff in each(system_staves) do + if system_staff.Resize < min_size then + min_size = system_staff.Resize + end + end + end + if min_size < 100 then + set_element_text(style_element, "smallStaffMag", min_size / 100) + set_element_text(style_element, "smallNoteMag", min_size / 100) + end + end + if music_font_name then + set_element_text(style_element, "musicalSymbolFont", music_font_name) + set_element_text(style_element, "musicalTextFont", music_font_name .. " Text") end end @@ -315,7 +353,8 @@ function write_line_measure_prefs(style_element) set_element_text(style_element, "startBarlineSingle", misc_prefs.LeftBarlineDisplaySingle) set_element_text(style_element, "startBarlineMultiple", misc_prefs.LeftBarlineDisplayMultiple) set_element_text(style_element, "bracketWidth", 0.5) -- hard-coded in Finale - set_element_text(style_element, "bracketDistance", -distance_prefs.GroupBracketDefaultDistance / EVPU_PER_SPACE) + -- Finale subtracts half the bracket width on layout for bracket distance (observed). + set_element_text(style_element, "bracketDistance", ((-distance_prefs.GroupBracketDefaultDistance) - 0.25 * EVPU_PER_SPACE) / EVPU_PER_SPACE) set_element_text(style_element, "akkoladeBarDistance", -distance_prefs.GroupBracketDefaultDistance / EVPU_PER_SPACE) set_element_text(style_element, "clefLeftMargin", distance_prefs.ClefSpaceBefore / EVPU_PER_SPACE) set_element_text(style_element, "keysigLeftMargin", distance_prefs.KeySpaceBefore / EVPU_PER_SPACE) @@ -328,7 +367,7 @@ function write_line_measure_prefs(style_element) -- differences in how MuseScore and Finale interpret these settings means the following two are better off left alone -- set_element_text(style_element, "systemHeaderDistance", distance_prefs.KeySpaceAfter / EVPU_PER_SPACE) -- set_element_text(style_element, "systemHeaderTimeSigDistance", distance_prefs.TimeSigSpaceAfter / EVPU_PER_SPACE) - set_element_text(style_element, "clefBarlineDistance", repeat_prefs.AfterClefSpace / EVPU_PER_SPACE) + set_element_text(style_element, "clefBarlineDistance", distance_prefs.ClefChangeOffset / EVPU_PER_SPACE) set_element_text(style_element, "timesigBarlineDistance", repeat_prefs.AfterClefSpace / EVPU_PER_SPACE) set_element_text(style_element, "measureRepeatNumberPos", -(music_character_prefs.VerticalTwoMeasureRepeatOffset + 0.5) / EVPU_PER_SPACE) set_element_text(style_element, "staffLineWidth", size_prefs.StaffLineThickness / EFIX_PER_SPACE) @@ -344,7 +383,7 @@ function write_line_measure_prefs(style_element) set_element_text(style_element, "genCourtesyClef", misc_prefs.CourtesyClefAtSystemEnd) set_element_text(style_element, "keySigCourtesyBarlineMode", misc_prefs.DoubleBarlineAtKeyChange) set_element_text(style_element, "timeSigCourtesyBarlineMode", 0) - set_element_text(style_element, "hideEmptyStaves", not current_is_part) + set_element_text(style_element, "hideEmptyStaves", score.calc_has_optimized_systems()) end function write_stem_prefs(style_element) @@ -371,10 +410,17 @@ function write_note_related_prefs(style_element) -- Finale randomly adds twice the stem width to the length of a beam stub. (Observed behavior) set_element_text(style_element, "beamMinLen", (size_prefs.BrokenBeamLength + (2 * size_prefs.StemLineThickness / EFIX_PER_EVPU)) / EVPU_PER_SPACE) set_element_text(style_element, "beamNoSlope", misc_prefs.BeamSlopeStyle == finale.BEAMSLOPE_FLATTENALL) - set_element_text(style_element, "dotMag", muse_mag_val(finale.FONTPREF_AUGMENTATIONDOT)) + local dot_mag = muse_mag_val(finale.FONTPREF_AUGMENTATIONDOT) + set_element_text(style_element, "dotMag", dot_mag) set_element_text(style_element, "dotNoteDistance", distance_prefs.AugmentationDotNoteSpace / EVPU_PER_SPACE) set_element_text(style_element, "dotRestDistance", distance_prefs.AugmentationDotNoteSpace / EVPU_PER_SPACE) - set_element_text(style_element, "dotDotDistance", distance_prefs.AugmentationDotSpace / EVPU_PER_SPACE) + local dot_width = (function() + local metrics = finale.FCTextMetrics() + metrics:LoadSymbol(music_character_prefs.SymbolAugmentationDot, default_music_font, 100) + return metrics:CalcWidthEVPUs() + end)() + -- MuseScore dot-dot width includes the dot whereas Finale's is from right edge of previous to left edge of next + set_element_text(style_element, "dotDotDistance", (distance_prefs.AugmentationDotSpace + dot_mag * dot_width) / EVPU_PER_SPACE) set_element_text(style_element, "articulationMag", muse_mag_val(finale.FONTPREF_ARTICULATION)) set_element_text(style_element, "graceNoteMag", size_prefs.GraceNoteSize / 100) set_element_text(style_element, "concertPitch", part_scope_prefs.DisplayInConcertPitch) @@ -383,7 +429,7 @@ function write_note_related_prefs(style_element) end function write_smart_shape_prefs(style_element) - set_element_text(style_element, "hairpinHeight", smart_shape_prefs.HairpinDefaultOpening / EVPU_PER_SPACE) + set_element_text(style_element, "hairpinHeight", smart_shape_prefs.HairpinDefaultShortOpening / EVPU_PER_SPACE) set_element_text(style_element, "hairpinContHeight", 0.5) -- not configurable in Finale: hard-coded to a half space write_category_text_font_pref(style_element, "hairpin", finale.DEFAULTCATID_DYNAMICS) write_line_prefs(style_element, "hairpin", smart_shape_prefs.HairpinLineWidth, smart_shape_prefs.LineDashLength, smart_shape_prefs.LineDashSpace) @@ -419,7 +465,7 @@ function write_measure_number_prefs(style_element) return "right,baseline" end end - local function horz_alignment(align) + local function horz_alignment(align) -- MuseScore 4.6 changes this to "left", "center", "right" if align == finale.MNALIGN_LEFT then return 0 elseif align == finale.MNALIGN_CENTER then @@ -484,6 +530,10 @@ end function write_tuplet_prefs(style_element) set_element_text(style_element, "tupletOutOfStaff", tuplet_prefs.AvoidStaff) + -- tupletNumberRythmicCenter and tupletExtendToEndOfDuration are 4.6 settings, but MuseScore 4.5 should ignore them + -- while MuseScore 4.6 picks them up even out of a 4.5 file. + set_element_text(style_element, "tupletNumberRythmicCenter", tuplet_prefs.CenterUsingDuration); -- 4.6 setting + set_element_text(style_element, "tupletExtendToEndOfDuration", tuplet_prefs.BracketFullDuration); -- 4.6 setting set_element_text(style_element, "tupletStemLeftDistance", tuplet_prefs.LeftExtension / EVPU_PER_SPACE) set_element_text(style_element, "tupletStemRightDistance", tuplet_prefs.RightExtension / EVPU_PER_SPACE) set_element_text(style_element, "tupletNoteLeftDistance", tuplet_prefs.LeftExtension / EVPU_PER_SPACE) diff --git a/src/library/score.lua b/src/library/score.lua index b47eb83b..f3b438a1 100644 --- a/src/library/score.lua +++ b/src/library/score.lua @@ -825,4 +825,31 @@ function score.calc_voice_staff(staff_num) return is_voice_staff end +--[[ +% calc_has_optimized_systems() + +Deterimines if this score contains optimized systems + +: (boolean) True if an optimized system is found +]] +function score.calc_has_optimized_systems() + local staff_systems = finale.FCStaffSystems() + staff_systems:LoadAll() + local scroll_view = finale.FCSystemStaves() + scroll_view:LoadScrollView() + for staff_system in each(staff_systems) do + local next_system = finale.FCSystemStaves() + next_system:LoadAllForItem(staff_system.ItemNo) + if next_system.Count ~= scroll_view.Count then + return true + end + for staff_index = 0, next_system.Count - 1 do + if next_system:GetItemAt(staff_index).Staff ~= scroll_view:GetItemAt(staff_index).Staff then + return true + end + end + end + return false +end + return score From 96ae810f598b05a1f5599f48b2da01201cf93696 Mon Sep 17 00:00:00 2001 From: Robert Patterson Date: Mon, 28 Jul 2025 13:56:06 -0500 Subject: [PATCH 2/2] update with RGP field --- src/font_map_legacy.lua | 42 +++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/font_map_legacy.lua b/src/font_map_legacy.lua index cc743ba7..6e4a16f9 100644 --- a/src/font_map_legacy.lua +++ b/src/font_map_legacy.lua @@ -35,7 +35,10 @@ context = { local function format_mapping(mapping) local codepoint_desc = "[" .. utils.format_codepoint(mapping.codepoint) .. "]" if mapping.glyph then - return "'" .. mapping.glyph .. "' " .. codepoint_desc + codepoint_desc = "'" .. mapping.glyph .. "' " .. codepoint_desc + end + if mapping.smuflFontName then + codepoint_desc = codepoint_desc .. "(" .. mapping.smuflFontName ..")" end return codepoint_desc end @@ -84,11 +87,30 @@ local function set_codepoint(control, codepoint) control:SetText(fcstr) end +local function on_smufl_popup(popup) + local dialog = popup:GetParent() + local smufl_box = dialog:GetControl("smufl_box") + local fcstr = finale.FCString() + popup:GetItemText(popup:GetSelectedItem(), fcstr) + smufl_box:SetFont(finale.FCFontInfo(fcstr.LuaString, 24)) +end + local function on_popup(popup) local legacy_codepoint = context.popup_keys[popup:GetSelectedItem() + 1] or 0 local current_mapping = legacy_codepoint > 0 and context.current_mapping[legacy_codepoint] local smufl_codepoint = current_mapping and current_mapping.codepoint or 0 local dialog = popup:GetParent() + if current_mapping and current_mapping.smuflFontName then + local smufl_list = dialog:GetControl("smufl_list") + for index = 0, smufl_list:GetCount() - 1 do + local str = finale.FCString() + smufl_list:GetItemText(index, str) + if str.LuaString == current_mapping.smuflFontName then + smufl_list:SetSelectedItem(index) + on_smufl_popup(smufl_list) + end + end + end set_codepoint(dialog:GetControl("legacy_box"), legacy_codepoint) set_codepoint(dialog:GetControl("smufl_box"), smufl_codepoint) end @@ -164,6 +186,7 @@ local function on_select_file(control) t.glyph = glyph t.codepoint = utils.parse_codepoint(v.codepoint) t.nameIsMakeMusic = v.nameIsMakeMusic + t.smuflFontName = v.smuflFontName if t.codepoint == 0xFFFD then local smufl_box = dialog:GetControl("smufl_box") local _, info = smufl_glyphs.get_glyph_info(glyph, smufl_box:CreateFontInfo()) @@ -200,14 +223,6 @@ local function on_symbol_select(box) enable_disable(dialog) end -local function on_smufl_popup(popup) - local dialog = popup:GetParent() - local smufl_box = dialog:GetControl("smufl_box") - local fcstr = finale.FCString() - popup:GetItemText(popup:GetSelectedItem(), fcstr) - smufl_box:SetFont(finale.FCFontInfo(fcstr.LuaString, 24)) -end - local function on_add_mapping(control) local dialog = control:GetParent() local popup = dialog:GetControl("mappings") @@ -221,13 +236,17 @@ local function on_add_mapping(control) return end end + local font = dialog:GetControl("smufl_box"):CreateFontInfo() current_mapping = {codepoint = smufl_point} - local glyph, info = smufl_glyphs.get_glyph_info(smufl_point, dialog:GetControl("smufl_box"):CreateFontInfo()) + local glyph, info = smufl_glyphs.get_glyph_info(smufl_point, font) if info then current_mapping.glyph = glyph else current_mapping.glyph = utils.format_codepoint(smufl_point) end + if font and smufl_point >= 0xF400 and smufl_point <= 0xF8FF then + current_mapping.smuflFontName = font.Name + end context.current_mapping[legacy_point] = current_mapping update_popup(popup, legacy_point) end @@ -264,6 +283,9 @@ local function emit_json(mapping, reverse_lookup) else table.insert(parts, '\t\t"description": ' .. quote("")) end + if entry.smuflFontName then + table.insert(parts, '\t\t"smuflFontName": ' .. quote(entry.smuflFontName)) + end return "{\n" .. table.concat(parts, ",\n") .. "\n\t}" end