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
52
56{
59
64 Bracket,
65
73
77
80 CurveTo,
81
85
89 Ellipse,
90
94
98
101 FillAlt,
102
105 FillSolid,
106
110
113 GoToStart,
114
117 LineWidth,
118
122 Rectangle,
123
126 RLineTo,
127
130 RMoveTo,
131
140
143 SetBlack,
144
147 SetDash,
148
151 SetFont,
152
155 SetGray,
156
159 SetWhite,
160
164 Slur,
165
169
186
189 Stroke,
190
195};
196
200{
204 std::vector<int> data;
205 };
206
211
213 struct CloneChar {
216 int unused2{};
218 char32_t codePoint{};
219 };
220
230
232 struct DrawChar {
233 char32_t codePoint{};
234 };
235
237 struct Ellipse {
240 };
241
248
250 struct LineWidth {
252 };
253
255 struct Rectangle {
258 };
259
261 struct RLineTo {
264 };
265
267 struct RMoveTo {
270 };
271
277 int extra{};
278
280 int startKindCode() const noexcept
281 { return static_cast<int>(static_cast<unsigned int>(packedKindCodes) & 0xFFFFu); }
282
284 int endKindCode() const noexcept
285 { return static_cast<int>((static_cast<unsigned int>(packedKindCodes) >> 16) & 0xFFFFu); }
286 };
287
293
295 struct SetFont {
297 SetFont(const DocumentWeakPtr& document) : font(document)
298 {}
300 };
301
303 struct SetGray {
304 int gray{};
305 };
306
318
336
355
357 enum class VerticalAlign {
358 Center = 1,
359 Left = 2,
360 Right = 3
361 };
362
367
368
370 using InstructionData = std::variant<
371 std::monostate, // for commands with no data
373 Bracket,
374 CloneChar,
375 CurveTo,
376 DrawChar,
377 Ellipse,
379 LineWidth,
380 Rectangle,
381 RLineTo,
382 RMoveTo,
384 SetDash,
385 SetFont,
386 SetGray,
387 Slur,
391 >;
392
395 struct Decoded
396 {
398 InstructionData data{std::monostate{}};
399
401 bool valid() const noexcept { return m_valid; }
402
406 template <typename T>
407 void setPayload(std::optional<T>&& optData)
408 {
409 if (optData) {
410 // Move the contained T into the variant
411 data = std::move(*optData);
412 m_valid = true;
413 } else {
414 // We *tried* to parse data and failed
415 m_valid = false;
416 }
417 }
418
419 private:
420 bool m_valid{true};
421 };
422
424 static std::optional<Undocumented> parseUndocumented(const std::vector<int>& data);
425
427 static std::optional<Bracket> parseBracket(const std::vector<int>& data);
428
430 static std::optional<CloneChar> parseCloneChar(const std::vector<int>& data);
431
433 static std::optional<CurveTo> parseCurveTo(const std::vector<int>& data);
434
436 static std::optional<DrawChar> parseDrawChar(const std::vector<int>& data);
437
439 static std::optional<Ellipse> parseEllipse(const std::vector<int>& data);
440
442 static std::optional<ExternalGraphic> parseExternalGraphic(const std::vector<int>& data);
443
445 static std::optional<LineWidth> parseLineWidth(const std::vector<int>& data);
446
448 static std::optional<Rectangle> parseRectangle(const std::vector<int>& data);
449
451 static std::optional<RLineTo> parseRLineTo(const std::vector<int>& data);
452
454 static std::optional<RMoveTo> parseRMoveTo(const std::vector<int>& data);
455
457 static std::optional<SetArrowhead> parseSetArrowhead(const std::vector<int>& data);
458
460 static std::optional<SetDash> parseSetDash(const std::vector<int>& data);
461
463 static std::optional<SetFont> parseSetFont(const DocumentWeakPtr& document, const std::vector<int>& data);
464
466 static std::optional<SetGray> parseSetGray(const std::vector<int>& data);
467
469 static std::optional<Slur> parseSlur(const std::vector<int>& data);
470
472 static std::optional<StartGroup> parseStartGroup(const std::vector<int>& data);
473
475 static std::optional<StartObject> parseStartObject(const std::vector<int>& data);
476
478 static std::optional<VerticalMode> parseVerticalMode(const std::vector<int>& data);
479};
480
481namespace others {
482
489class ShapeData : public OthersArray<int>
490{
491 std::string_view xmlTag() const override { return XmlNodeName; }
492
493public:
495
496 constexpr static std::string_view XmlNodeName = "shapeData";
497 static const xml::XmlElementArray<ShapeData>& xmlMappingArray();
498};
499
500#ifndef DOXYGEN_SHOULD_IGNORE_THIS
501class ShapeDefTestAccessor; // used by tests to access private iterator in ShapeDef
502#endif
503
504class ShapeInstructionList;
511class ShapeDef : public OthersBase
512{
513private:
515 bool iterateInstructions(std::function<bool(ShapeDefInstructionType, std::vector<int>)> callback) const;
516
517 friend class ShapeDefTestAccessor; // gives tests access, but users don't see it
518
519public:
521 explicit ShapeDef(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
522 : OthersBase(document, partId, shareMode, cmper)
523 {
524 }
525
530 enum class ShapeType
531 {
532 Other = 0,
533 Articulation = 1,
534 Barline = 2,
535 Executable = 3,
536 Expression = 4,
537 CustomStem = 5,
538 Frame = 6,
539 Arrowhead = 7,
540 Fretboard = 8,
541 Clef = 9
542 };
543
544 Cmper instructionList{};
545 Cmper dataList{};
546 ShapeType shapeType{};
547
549 bool isBlank() const
550 { return instructionList == 0; }
551
555 bool iterateInstructions(std::function<bool(const ShapeDefInstruction::Decoded&)> callback) const;
556
559 KnownShapeDefType recognize() const;
560
567 std::optional<Evpu> calcWidth() const;
568
573 CurveContourDirection calcSlurContour() const;
574
575 constexpr static std::string_view XmlNodeName = "shapeDef";
576 static const xml::XmlElementArray<ShapeDef>& xmlMappingArray();
577};
578
585class ShapeInstructionList : public OthersBase
586{
587public:
589 explicit ShapeInstructionList(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
590 : OthersBase(document, partId, shareMode, cmper)
591 {
592 }
593
604
605 std::vector<std::shared_ptr<InstructionInfo>> instructions;
606
607 constexpr static std::string_view XmlNodeName = "shapeList";
608 static const xml::XmlElementArray<ShapeInstructionList>& xmlMappingArray();
609};
610
611} // namespace others
612} // namespace dom
613} // 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:66
OthersArray(const DocumentWeakPtr &document, Cmper partId, ShareMode shareMode, Cmper cmper)
Constructor function.
Definition BaseClasses.h:359
OthersBase(const DocumentWeakPtr &document, Cmper partId, ShareMode shareMode, Cmper cmper, std::optional< Inci > inci=std::nullopt)
Constructs an OthersBase object.
Definition BaseClasses.h:299
BracketStyle
Bracket types.
Definition Details.h:646
An instruction in the shape.
Definition ShapeDesigner.h:596
int numData
the number of data items consumed by this instruction (See ShapeData.)
Definition ShapeDesigner.h:599
static const xml::XmlElementArray< InstructionInfo > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
ShapeDefInstructionType type
the type of instruction
Definition ShapeDesigner.h:600
@ 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.
@ PedalArrowheadUp
Upward wedge used for pedal markings.
@ 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.
@ 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:60
int32_t Evpu16ths
1/16 of an EVPU.
Definition Fundamentals.h:59
int32_t Evpu
EVPU value (288 per inch)
Definition Fundamentals.h:57
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
@ Blank
Blank clef (invisible, no symbol).
ShapeDefInstructionType
Defines the instruction types for Shape Designer shapes.
Definition ShapeDesigner.h:56
@ Undocumented
catch-all for possible undocumented instruction tags.
std::weak_ptr< Document > DocumentWeakPtr
Shared weak Document pointer.
Definition BaseClasses.h:57
std::vector< XmlElementDescriptor< T > > XmlElementArray
an array type for XmlElementDescriptor instances.
Definition XmlInterface.h:127
object model for musx file (enigmaxml)
Definition BaseClasses.h:36
Holds the parsed data for a Bracket instruction.
Definition ShapeDesigner.h:208
details::Bracket::BracketStyle bracketStyle
The style of bracket being created.
Definition ShapeDesigner.h:209
Holds the parsed data for a CloneChar instruction.
Definition ShapeDesigner.h:213
int baselineShift
Baseline shift in EMs (1/1000 of current point size).
Definition ShapeDesigner.h:217
int unused2
Unused/undocumented field at index 2.
Definition ShapeDesigner.h:216
char32_t codePoint
The 32-bit codepoint of the character to clone.
Definition ShapeDesigner.h:218
Evpu dy
The Y coordinate of the endpoint (currently ignored).
Definition ShapeDesigner.h:215
Evpu dx
The X coordinate of the endpoint (relative to current point).
Definition ShapeDesigner.h:214
Holds the parsed data for a CurveTo instruction.
Definition ShapeDesigner.h:222
Evpu c1dx
Relative X offset of the first control point.
Definition ShapeDesigner.h:223
Evpu c2dy
Relative Y offset of the second control point.
Definition ShapeDesigner.h:226
Evpu edy
Relative Y offset of the end point.
Definition ShapeDesigner.h:228
Evpu c2dx
Relative X offset of the second control point.
Definition ShapeDesigner.h:225
Evpu c1dy
Relative Y offset of the first control point.
Definition ShapeDesigner.h:224
Evpu edx
Relative X offset of the end point.
Definition ShapeDesigner.h:227
Contains the parsed instruction type with its data.
Definition ShapeDesigner.h:396
bool valid() const noexcept
Returns true is the data is valid.
Definition ShapeDesigner.h:401
void setPayload(std::optional< T > &&optData)
Sets the payload.
Definition ShapeDesigner.h:407
ShapeDefInstructionType type
Instruction type.
Definition ShapeDesigner.h:397
InstructionData data
Data for instruction.
Definition ShapeDesigner.h:398
Holds the parsed data for a DrawChar instruction.
Definition ShapeDesigner.h:232
char32_t codePoint
The 32-bit codepoint of the character to draw.
Definition ShapeDesigner.h:233
Holds the parsed data for an Ellipse instruction.
Definition ShapeDesigner.h:237
Evpu height
The height of the bounding rectangle.
Definition ShapeDesigner.h:239
Evpu width
The width of the bounding rectangle.
Definition ShapeDesigner.h:238
Holds the parsed data for an ExternalGraphic instruction.
Definition ShapeDesigner.h:243
Evpu height
The height of the placed graphic.
Definition ShapeDesigner.h:245
Cmper cmper
The cmper of the graphic. See others::PageGraphicAssign::graphicCmper for explanation.
Definition ShapeDesigner.h:246
Evpu width
The width of the placed graphic.
Definition ShapeDesigner.h:244
Holds the parsed data for a LineWidth instruction.
Definition ShapeDesigner.h:250
Efix efix
The line width in Efix units.
Definition ShapeDesigner.h:251
Holds the parsed data for an RLineTo instruction.
Definition ShapeDesigner.h:261
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:262
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:263
Holds the parsed data for an RMoveTo 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 a Rectangle instruction.
Definition ShapeDesigner.h:255
Evpu height
The height of the rectangle.
Definition ShapeDesigner.h:257
Evpu width
The width of the rectangle.
Definition ShapeDesigner.h:256
Holds the parsed data for a SetArrowhead instruction.
Definition ShapeDesigner.h:273
int startArrowId
Raw word 1. Start arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:275
int extra
Raw word 3. Unknown (value persists when edited by plugin; no observed rendering effect in current ex...
Definition ShapeDesigner.h:277
int endKindCode() const noexcept
Returns the end kind code from packedKindCodes (high 16 bits).
Definition ShapeDesigner.h:284
int endArrowId
Raw word 2. End arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:276
int startKindCode() const noexcept
Returns the start kind code from packedKindCodes (low 16 bits).
Definition ShapeDesigner.h:280
int packedKindCodes
Raw word 0. Packs start/end kind codes (e.g. 0x00010001 preset/preset, 0x00020002 custom/custom).
Definition ShapeDesigner.h:274
Holds the parsed data for a SetDash instruction.
Definition ShapeDesigner.h:289
Evpu spaceLength
Space between dashes in Evpu.
Definition ShapeDesigner.h:291
Evpu dashLength
Length of each dash segment in Evpu.
Definition ShapeDesigner.h:290
Holds the parsed data for a SetFont instruction.
Definition ShapeDesigner.h:295
SetFont(const DocumentWeakPtr &document)
Constructor function.
Definition ShapeDesigner.h:297
FontInfo font
the parsed font
Definition ShapeDesigner.h:299
Holds the parsed data for a SetGray instruction.
Definition ShapeDesigner.h:303
int gray
Gray value between 0 (black) and 100 (white).
Definition ShapeDesigner.h:304
Holds the parsed data for a Slur instruction.
Definition ShapeDesigner.h:310
Evpu16ths edx
Relative X offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:315
Evpu16ths c2dx
Relative X offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:313
Evpu16ths c1dx
Relative X offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:311
Evpu16ths c2dy
Relative Y offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:314
Evpu16ths edy
Relative Y offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:316
Evpu16ths c1dy
Relative Y offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:312
Holds the parsed data for a StartGroup instruction.
Definition ShapeDesigner.h:339
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:345
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:341
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:353
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:347
int rotation
Definition ShapeDesigner.h:348
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:343
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:344
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:352
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:346
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:342
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:340
Holds the parsed data for a StartObject instruction.
Definition ShapeDesigner.h:320
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:323
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:322
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:326
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:328
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:334
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:327
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:324
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:333
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:321
int rotation
Definition ShapeDesigner.h:329
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:325
Holds the parsed data for an Undocumented instruction.
Definition ShapeDesigner.h:203
std::vector< int > data
Raw data items for the undocumented instruction.
Definition ShapeDesigner.h:204
Holds the parsed data for a VerticalMode instruction.
Definition ShapeDesigner.h:364
VerticalAlign mode
The pen vertical alignment mode.
Definition ShapeDesigner.h:365
Helper functions and structs for decoding instruction data vectors in others::ShapeDef.
Definition ShapeDesigner.h:200
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:357
@ 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:391
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