MUSX Document Model
Loading...
Searching...
No Matches
ShapeDesigner.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include "musx/util/Logger.h"
25#include "musx/util/Fraction.h"
26
27#include "BaseClasses.h"
28#include "CommonClasses.h"
29#include "Details.h"
30
31 // do not add other dom class dependencies. Use Implementations.cpp for implementations that need total class access.
32
33namespace musx {
34namespace dom {
35
58
62{
65
70 Bracket,
71
79
83
86 CurveTo,
87
91
95 Ellipse,
96
100
104
107 FillAlt,
108
111 FillSolid,
112
116
119 GoToStart,
120
123 LineWidth,
124
128 Rectangle,
129
132 RLineTo,
133
136 RMoveTo,
137
146
149 SetBlack,
150
153 SetDash,
154
157 SetFont,
158
161 SetGray,
162
165 SetWhite,
166
170 Slur,
171
175
192
195 Stroke,
196
201};
202
206{
210 std::vector<int> data;
211 };
212
217
219 struct CloneChar {
222 int unused2{};
224 char32_t codePoint{};
225 };
226
236
238 struct DrawChar {
239 char32_t codePoint{};
240 };
241
243 struct Ellipse {
246 };
247
254
256 struct LineWidth {
258 };
259
261 struct Rectangle {
264 };
265
267 struct RLineTo {
270 };
271
273 struct RMoveTo {
276 };
277
283 int extra{};
284
286 int startKindCode() const noexcept
287 { return static_cast<int>(static_cast<unsigned int>(packedKindCodes) & 0xFFFFu); }
288
290 int endKindCode() const noexcept
291 { return static_cast<int>((static_cast<unsigned int>(packedKindCodes) >> 16) & 0xFFFFu); }
292 };
293
299
301 struct SetFont {
303 SetFont(const DocumentWeakPtr& document) : font(document)
304 {}
306 };
307
309 struct SetGray {
310 int gray{};
311 };
312
324
342
361
363 enum class VerticalAlign {
364 Center = 1,
365 Left = 2,
366 Right = 3
367 };
368
373
374
376 using InstructionData = std::variant<
377 std::monostate, // for commands with no data
379 Bracket,
380 CloneChar,
381 CurveTo,
382 DrawChar,
383 Ellipse,
385 LineWidth,
386 Rectangle,
387 RLineTo,
388 RMoveTo,
390 SetDash,
391 SetFont,
392 SetGray,
393 Slur,
397 >;
398
401 struct Decoded
402 {
404 InstructionData data{std::monostate{}};
405
407 bool valid() const noexcept { return m_valid; }
408
412 template <typename T>
413 void setPayload(std::optional<T>&& optData)
414 {
415 if (optData) {
416 // Move the contained T into the variant
417 data = std::move(*optData);
418 m_valid = true;
419 } else {
420 // We *tried* to parse data and failed
421 m_valid = false;
422 }
423 }
424
425 private:
426 bool m_valid{true};
427 };
428
430 static std::optional<Undocumented> parseUndocumented(const std::vector<int>& data);
431
433 static std::optional<Bracket> parseBracket(const std::vector<int>& data);
434
436 static std::optional<CloneChar> parseCloneChar(const std::vector<int>& data);
437
439 static std::optional<CurveTo> parseCurveTo(const std::vector<int>& data);
440
442 static std::optional<DrawChar> parseDrawChar(const std::vector<int>& data);
443
445 static std::optional<Ellipse> parseEllipse(const std::vector<int>& data);
446
448 static std::optional<ExternalGraphic> parseExternalGraphic(const std::vector<int>& data);
449
451 static std::optional<LineWidth> parseLineWidth(const std::vector<int>& data);
452
454 static std::optional<Rectangle> parseRectangle(const std::vector<int>& data);
455
457 static std::optional<RLineTo> parseRLineTo(const std::vector<int>& data);
458
460 static std::optional<RMoveTo> parseRMoveTo(const std::vector<int>& data);
461
463 static std::optional<SetArrowhead> parseSetArrowhead(const std::vector<int>& data);
464
466 static std::optional<SetDash> parseSetDash(const std::vector<int>& data);
467
469 static std::optional<SetFont> parseSetFont(const DocumentWeakPtr& document, const std::vector<int>& data);
470
472 static std::optional<SetGray> parseSetGray(const std::vector<int>& data);
473
475 static std::optional<Slur> parseSlur(const std::vector<int>& data);
476
478 static std::optional<StartGroup> parseStartGroup(const std::vector<int>& data);
479
481 static std::optional<StartObject> parseStartObject(const std::vector<int>& data);
482
484 static std::optional<VerticalMode> parseVerticalMode(const std::vector<int>& data);
485};
486
487namespace others {
488
495class ShapeData : public OthersArray<int>
496{
497 std::string_view xmlTag() const override { return XmlNodeName; }
498
499public:
501
502 constexpr static std::string_view XmlNodeName = "shapeData";
503 static const xml::XmlElementArray<ShapeData>& xmlMappingArray();
504};
505
506#ifndef DOXYGEN_SHOULD_IGNORE_THIS
507class ShapeDefTestAccessor; // used by tests to access private iterator in ShapeDef
508#endif
509
510class ShapeInstructionList;
517class ShapeDef : public OthersBase
518{
519private:
521 bool iterateInstructions(std::function<bool(ShapeDefInstructionType, std::vector<int>)> callback) const;
522
523 friend class ShapeDefTestAccessor; // gives tests access, but users don't see it
524
525public:
527 explicit ShapeDef(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
528 : OthersBase(document, partId, shareMode, cmper)
529 {
530 }
531
536 enum class ShapeType
537 {
538 Other = 0,
539 Articulation = 1,
540 Barline = 2,
541 Executable = 3,
542 Expression = 4,
543 CustomStem = 5,
544 Frame = 6,
545 Arrowhead = 7,
546 Fretboard = 8,
547 Clef = 9
548 };
549
550 Cmper instructionList{};
551 Cmper dataList{};
552 ShapeType shapeType{};
553
555 bool isBlank() const
556 { return instructionList == 0; }
557
561 bool iterateInstructions(std::function<bool(const ShapeDefInstruction::Decoded&)> callback) const;
562
565 KnownShapeDefType recognize() const;
566
573 std::optional<Evpu> calcWidth() const;
574
579 CurveContourDirection calcSlurContour() const;
580
581 constexpr static std::string_view XmlNodeName = "shapeDef";
582 static const xml::XmlElementArray<ShapeDef>& xmlMappingArray();
583};
584
591class ShapeInstructionList : public OthersBase
592{
593public:
595 explicit ShapeInstructionList(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
596 : OthersBase(document, partId, shareMode, cmper)
597 {
598 }
599
610
611 std::vector<std::shared_ptr<InstructionInfo>> instructions;
612
613 constexpr static std::string_view XmlNodeName = "shapeList";
614 static const xml::XmlElementArray<ShapeInstructionList>& xmlMappingArray();
615};
616
617} // namespace others
618} // namespace dom
619} // namespace musx
ShareMode
Describes how this instance is shared between part and score.
Definition BaseClasses.h:91
Represents the default font settings for a particular element type.
Definition CommonClasses.h:67
OthersArray(const DocumentWeakPtr &document, Cmper partId, ShareMode shareMode, Cmper cmper)
Constructor function.
Definition BaseClasses.h:320
OthersBase(const DocumentWeakPtr &document, Cmper partId, ShareMode shareMode, Cmper cmper, std::optional< Inci > inci=std::nullopt)
Constructs an OthersBase object.
Definition BaseClasses.h:260
BracketStyle
Bracket types.
Definition Details.h:693
An instruction in the shape.
Definition ShapeDesigner.h:602
int numData
the number of data items consumed by this instruction (See ShapeData.)
Definition ShapeDesigner.h:605
static const xml::XmlElementArray< InstructionInfo > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
ShapeDefInstructionType type
the type of instruction
Definition ShapeDesigner.h:606
@ Other
Other/unknown text encoding.
CurveContourDirection
Curve contour direction for ties and slurs.
Definition EnumClasses.h:62
KnownShapeDefType
Enumerates the shape types we can recognize semantically.
Definition ShapeDesigner.h:39
@ PedalArrowheadShortUpDownLongUp
Pedal arrowhead: short up, down, long up.
@ PedalArrowheadDown
Downward wedge used for pedal markings.
@ FingernailPizzCurveUp
Fingernail pizzicato double curve arching upward.
@ SnapPizzicatoAbove
Snap pizzicato mark with vertical stem above the circle.
@ BuzzPizzicato
Buzz pizzicato mark with horizontal stem.
@ FingernailPizzCurveDown
Fingernail pizzicato double curve arching downward.
@ PedalArrowheadUp
Upward wedge used for pedal markings.
@ SnapPizzicatoBelow
Snap pizzicato mark with vertical stem below the circle.
@ Unrecognized
Fallback when recognition fails.
@ SlurTieCurveRight
Horizontal slur or tie shape curving toward the right.
@ PedalArrowheadLongUpDownShortUp
Pedal arrowhead: long up, down, short up.
@ TenutoMark
A horizontal tenuto mark, typically used as an articulation symbol.
@ VerticalLineRightHooks
Vertical line with short horizontal hooks extending to the right at both ends.
@ SlurTieCurveLeft
Horizontal slur or tie shape curving toward the left.
int32_t Efix
EFIX value (64 per EVPU, 64*288=18432 per inch)
Definition Fundamentals.h:62
int32_t Evpu16ths
1/16 of an EVPU.
Definition Fundamentals.h:61
int32_t Evpu
EVPU value (288 per inch)
Definition Fundamentals.h:59
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:57
@ Blank
Blank clef (invisible, no symbol).
ShapeDefInstructionType
Defines the instruction types for Shape Designer shapes.
Definition ShapeDesigner.h:62
@ Undocumented
catch-all for possible undocumented instruction tags.
std::weak_ptr< Document > DocumentWeakPtr
Shared weak Document pointer.
Definition DocumentElement.h:37
std::vector< XmlElementDescriptor< T > > XmlElementArray
an array type for XmlElementDescriptor instances.
Definition XmlInterface.h:127
object model for musx file (enigmaxml)
Definition BaseClasses.h:38
Holds the parsed data for a Bracket instruction.
Definition ShapeDesigner.h:214
details::Bracket::BracketStyle bracketStyle
The style of bracket being created.
Definition ShapeDesigner.h:215
Holds the parsed data for a CloneChar instruction.
Definition ShapeDesigner.h:219
int baselineShift
Baseline shift in EMs (1/1000 of current point size).
Definition ShapeDesigner.h:223
int unused2
Unused/undocumented field at index 2.
Definition ShapeDesigner.h:222
char32_t codePoint
The 32-bit codepoint of the character to clone.
Definition ShapeDesigner.h:224
Evpu dy
The Y coordinate of the endpoint (currently ignored).
Definition ShapeDesigner.h:221
Evpu dx
The X coordinate of the endpoint (relative to current point).
Definition ShapeDesigner.h:220
Holds the parsed data for a CurveTo instruction.
Definition ShapeDesigner.h:228
Evpu c1dx
Relative X offset of the first control point.
Definition ShapeDesigner.h:229
Evpu c2dy
Relative Y offset of the second control point.
Definition ShapeDesigner.h:232
Evpu edy
Relative Y offset of the end point.
Definition ShapeDesigner.h:234
Evpu c2dx
Relative X offset of the second control point.
Definition ShapeDesigner.h:231
Evpu c1dy
Relative Y offset of the first control point.
Definition ShapeDesigner.h:230
Evpu edx
Relative X offset of the end point.
Definition ShapeDesigner.h:233
Contains the parsed instruction type with its data.
Definition ShapeDesigner.h:402
bool valid() const noexcept
Returns true is the data is valid.
Definition ShapeDesigner.h:407
void setPayload(std::optional< T > &&optData)
Sets the payload.
Definition ShapeDesigner.h:413
ShapeDefInstructionType type
Instruction type.
Definition ShapeDesigner.h:403
InstructionData data
Data for instruction.
Definition ShapeDesigner.h:404
Holds the parsed data for a DrawChar instruction.
Definition ShapeDesigner.h:238
char32_t codePoint
The 32-bit codepoint of the character to draw.
Definition ShapeDesigner.h:239
Holds the parsed data for an Ellipse instruction.
Definition ShapeDesigner.h:243
Evpu height
The height of the bounding rectangle.
Definition ShapeDesigner.h:245
Evpu width
The width of the bounding rectangle.
Definition ShapeDesigner.h:244
Holds the parsed data for an ExternalGraphic instruction.
Definition ShapeDesigner.h:249
Evpu height
The height of the placed graphic.
Definition ShapeDesigner.h:251
Cmper cmper
The cmper of the graphic. See others::PageGraphicAssign::graphicCmper for explanation.
Definition ShapeDesigner.h:252
Evpu width
The width of the placed graphic.
Definition ShapeDesigner.h:250
Holds the parsed data for a LineWidth instruction.
Definition ShapeDesigner.h:256
Efix efix
The line width in Efix units.
Definition ShapeDesigner.h:257
Holds the parsed data for an RLineTo instruction.
Definition ShapeDesigner.h:267
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:268
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:269
Holds the parsed data for an RMoveTo instruction.
Definition ShapeDesigner.h:273
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:274
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:275
Holds the parsed data for a Rectangle instruction.
Definition ShapeDesigner.h:261
Evpu height
The height of the rectangle.
Definition ShapeDesigner.h:263
Evpu width
The width of the rectangle.
Definition ShapeDesigner.h:262
Holds the parsed data for a SetArrowhead instruction.
Definition ShapeDesigner.h:279
int startArrowId
Raw word 1. Start arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:281
int extra
Raw word 3. Unknown (value persists when edited by plugin; no observed rendering effect in current ex...
Definition ShapeDesigner.h:283
int endKindCode() const noexcept
Returns the end kind code from packedKindCodes (high 16 bits).
Definition ShapeDesigner.h:290
int endArrowId
Raw word 2. End arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:282
int startKindCode() const noexcept
Returns the start kind code from packedKindCodes (low 16 bits).
Definition ShapeDesigner.h:286
int packedKindCodes
Raw word 0. Packs start/end kind codes (e.g. 0x00010001 preset/preset, 0x00020002 custom/custom).
Definition ShapeDesigner.h:280
Holds the parsed data for a SetDash instruction.
Definition ShapeDesigner.h:295
Evpu spaceLength
Space between dashes in Evpu.
Definition ShapeDesigner.h:297
Evpu dashLength
Length of each dash segment in Evpu.
Definition ShapeDesigner.h:296
Holds the parsed data for a SetFont instruction.
Definition ShapeDesigner.h:301
SetFont(const DocumentWeakPtr &document)
Constructor function.
Definition ShapeDesigner.h:303
FontInfo font
the parsed font
Definition ShapeDesigner.h:305
Holds the parsed data for a SetGray instruction.
Definition ShapeDesigner.h:309
int gray
Gray value between 0 (black) and 100 (white).
Definition ShapeDesigner.h:310
Holds the parsed data for a Slur instruction.
Definition ShapeDesigner.h:316
Evpu16ths edx
Relative X offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:321
Evpu16ths c2dx
Relative X offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:319
Evpu16ths c1dx
Relative X offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:317
Evpu16ths c2dy
Relative Y offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:320
Evpu16ths edy
Relative Y offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:322
Evpu16ths c1dy
Relative Y offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:318
Holds the parsed data for a StartGroup instruction.
Definition ShapeDesigner.h:345
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:351
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:347
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:359
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:353
int rotation
Definition ShapeDesigner.h:354
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:349
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:350
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:358
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:352
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:348
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:346
Holds the parsed data for a StartObject instruction.
Definition ShapeDesigner.h:326
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:329
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:328
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:332
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:334
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:340
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:333
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:330
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:339
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:327
int rotation
Definition ShapeDesigner.h:335
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:331
Holds the parsed data for an Undocumented instruction.
Definition ShapeDesigner.h:209
std::vector< int > data
Raw data items for the undocumented instruction.
Definition ShapeDesigner.h:210
Holds the parsed data for a VerticalMode instruction.
Definition ShapeDesigner.h:370
VerticalAlign mode
The pen vertical alignment mode.
Definition ShapeDesigner.h:371
Helper functions and structs for decoding instruction data vectors in others::ShapeDef.
Definition ShapeDesigner.h:206
static std::optional< SetFont > parseSetFont(const DocumentWeakPtr &document, const std::vector< int > &data)
Attempts to parse a SetFont instruction.
Definition ShapeDesigner.cpp:210
static std::optional< ExternalGraphic > parseExternalGraphic(const std::vector< int > &data)
Attempts to parse an ExternalGraphic instruction.
Definition ShapeDesigner.cpp:129
static std::optional< Slur > parseSlur(const std::vector< int > &data)
Attempts to parse a Slur instruction.
Definition ShapeDesigner.cpp:234
static std::optional< LineWidth > parseLineWidth(const std::vector< int > &data)
Attempts to parse a LineWidth instruction.
Definition ShapeDesigner.cpp:142
static std::optional< VerticalMode > parseVerticalMode(const std::vector< int > &data)
Attempts to parse a VerticalMode instruction.
Definition ShapeDesigner.cpp:289
static std::optional< SetGray > parseSetGray(const std::vector< int > &data)
Attempts to parse a SetGray instruction.
Definition ShapeDesigner.cpp:223
static std::optional< DrawChar > parseDrawChar(const std::vector< int > &data)
Attempts to parse a DrawChar instruction.
Definition ShapeDesigner.cpp:108
static std::optional< StartObject > parseStartObject(const std::vector< int > &data)
Attempts to parse a StartObject instruction.
Definition ShapeDesigner.cpp:268
VerticalAlign
Pen vertical alignment modes for the VerticalMode instruction.
Definition ShapeDesigner.h:363
@ Center
Draw line centered on the coordinates.
@ Right
Draw line on the "right" side of the coordinates.
@ Left
Draw line on the "left" side of the coordinates.
static std::optional< SetArrowhead > parseSetArrowhead(const std::vector< int > &data)
Attempts to parse a SetArrowhead instruction.
Definition ShapeDesigner.cpp:184
static std::optional< StartGroup > parseStartGroup(const std::vector< int > &data)
Attempts to parse a StartGroup instruction.
Definition ShapeDesigner.cpp:247
static std::optional< Rectangle > parseRectangle(const std::vector< int > &data)
Attempts to parse a Rectangle instruction.
Definition ShapeDesigner.cpp:151
static std::optional< RLineTo > parseRLineTo(const std::vector< int > &data)
Attempts to parse an RLineTo instruction.
Definition ShapeDesigner.cpp:163
static std::optional< RMoveTo > parseRMoveTo(const std::vector< int > &data)
Attempts to parse an RMoveTo instruction.
Definition ShapeDesigner.cpp:172
static std::optional< Ellipse > parseEllipse(const std::vector< int > &data)
Attempts to parse an Ellipse instruction.
Definition ShapeDesigner.cpp:117
static std::optional< SetDash > parseSetDash(const std::vector< int > &data)
Attempts to parse a SetDash instruction.
Definition ShapeDesigner.cpp:198
std::variant< std::monostate, Undocumented, Bracket, CloneChar, CurveTo, DrawChar, Ellipse, ExternalGraphic, LineWidth, Rectangle, RLineTo, RMoveTo, SetArrowhead, SetDash, SetFont, SetGray, Slur, StartGroup, StartObject, VerticalMode > InstructionData
A variant for passing specific data per instruction type.
Definition ShapeDesigner.h:397
static std::optional< CloneChar > parseCloneChar(const std::vector< int > &data)
Attempts to parse a CloneChar instruction.
Definition ShapeDesigner.cpp:80
static std::optional< CurveTo > parseCurveTo(const std::vector< int > &data)
Attempts to parse a CurveTo instruction.
Definition ShapeDesigner.cpp:95
static std::optional< Undocumented > parseUndocumented(const std::vector< int > &data)
Attempts to parse an Undocumented instruction (raw passthrough).
Definition ShapeDesigner.cpp:46
static std::optional< Bracket > parseBracket(const std::vector< int > &data)
Attempts to parse a Bracket instruction.
Definition ShapeDesigner.cpp:53