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
53
57{
60
65 Bracket,
66
74
78
81 CurveTo,
82
86
90 Ellipse,
91
95
99
102 FillAlt,
103
106 FillSolid,
107
111
114 GoToStart,
115
118 LineWidth,
119
123 Rectangle,
124
127 RLineTo,
128
131 RMoveTo,
132
141
144 SetBlack,
145
148 SetDash,
149
152 SetFont,
153
156 SetGray,
157
160 SetWhite,
161
165 Slur,
166
170
187
190 Stroke,
191
196};
197
201{
205 std::vector<int> data;
206 };
207
212
214 struct CloneChar {
217 int unused2{};
219 char32_t codePoint{};
220 };
221
231
233 struct DrawChar {
234 char32_t codePoint{};
235 };
236
238 struct Ellipse {
241 };
242
249
251 struct LineWidth {
253 };
254
256 struct Rectangle {
259 };
260
262 struct RLineTo {
265 };
266
268 struct RMoveTo {
271 };
272
278 int extra{};
279
281 int startKindCode() const noexcept
282 { return static_cast<int>(static_cast<unsigned int>(packedKindCodes) & 0xFFFFu); }
283
285 int endKindCode() const noexcept
286 { return static_cast<int>((static_cast<unsigned int>(packedKindCodes) >> 16) & 0xFFFFu); }
287 };
288
294
296 struct SetFont {
298 SetFont(const DocumentWeakPtr& document) : font(document)
299 {}
301 };
302
304 struct SetGray {
305 int gray{};
306 };
307
319
337
356
358 enum class VerticalAlign {
359 Center = 1,
360 Left = 2,
361 Right = 3
362 };
363
368
369
371 using InstructionData = std::variant<
372 std::monostate, // for commands with no data
374 Bracket,
375 CloneChar,
376 CurveTo,
377 DrawChar,
378 Ellipse,
380 LineWidth,
381 Rectangle,
382 RLineTo,
383 RMoveTo,
385 SetDash,
386 SetFont,
387 SetGray,
388 Slur,
392 >;
393
396 struct Decoded
397 {
399 InstructionData data{std::monostate{}};
400
402 bool valid() const noexcept { return m_valid; }
403
407 template <typename T>
408 void setPayload(std::optional<T>&& optData)
409 {
410 if (optData) {
411 // Move the contained T into the variant
412 data = std::move(*optData);
413 m_valid = true;
414 } else {
415 // We *tried* to parse data and failed
416 m_valid = false;
417 }
418 }
419
420 private:
421 bool m_valid{true};
422 };
423
425 static std::optional<Undocumented> parseUndocumented(const std::vector<int>& data);
426
428 static std::optional<Bracket> parseBracket(const std::vector<int>& data);
429
431 static std::optional<CloneChar> parseCloneChar(const std::vector<int>& data);
432
434 static std::optional<CurveTo> parseCurveTo(const std::vector<int>& data);
435
437 static std::optional<DrawChar> parseDrawChar(const std::vector<int>& data);
438
440 static std::optional<Ellipse> parseEllipse(const std::vector<int>& data);
441
443 static std::optional<ExternalGraphic> parseExternalGraphic(const std::vector<int>& data);
444
446 static std::optional<LineWidth> parseLineWidth(const std::vector<int>& data);
447
449 static std::optional<Rectangle> parseRectangle(const std::vector<int>& data);
450
452 static std::optional<RLineTo> parseRLineTo(const std::vector<int>& data);
453
455 static std::optional<RMoveTo> parseRMoveTo(const std::vector<int>& data);
456
458 static std::optional<SetArrowhead> parseSetArrowhead(const std::vector<int>& data);
459
461 static std::optional<SetDash> parseSetDash(const std::vector<int>& data);
462
464 static std::optional<SetFont> parseSetFont(const DocumentWeakPtr& document, const std::vector<int>& data);
465
467 static std::optional<SetGray> parseSetGray(const std::vector<int>& data);
468
470 static std::optional<Slur> parseSlur(const std::vector<int>& data);
471
473 static std::optional<StartGroup> parseStartGroup(const std::vector<int>& data);
474
476 static std::optional<StartObject> parseStartObject(const std::vector<int>& data);
477
479 static std::optional<VerticalMode> parseVerticalMode(const std::vector<int>& data);
480};
481
482namespace others {
483
490class ShapeData : public OthersArray<int>
491{
492 std::string_view xmlTag() const override { return XmlNodeName; }
493
494public:
496
497 constexpr static std::string_view XmlNodeName = "shapeData";
498 static const xml::XmlElementArray<ShapeData>& xmlMappingArray();
499};
500
501#ifndef DOXYGEN_SHOULD_IGNORE_THIS
502class ShapeDefTestAccessor; // used by tests to access private iterator in ShapeDef
503#endif
504
505class ShapeInstructionList;
512class ShapeDef : public OthersBase
513{
514private:
516 bool iterateInstructions(std::function<bool(ShapeDefInstructionType, std::vector<int>)> callback) const;
517
518 friend class ShapeDefTestAccessor; // gives tests access, but users don't see it
519
520public:
522 explicit ShapeDef(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
523 : OthersBase(document, partId, shareMode, cmper)
524 {
525 }
526
531 enum class ShapeType
532 {
533 Other = 0,
534 Articulation = 1,
535 Barline = 2,
536 Executable = 3,
537 Expression = 4,
538 CustomStem = 5,
539 Frame = 6,
540 Arrowhead = 7,
541 Fretboard = 8,
542 Clef = 9
543 };
544
545 Cmper instructionList{};
546 Cmper dataList{};
547 ShapeType shapeType{};
548
550 bool isBlank() const
551 { return instructionList == 0; }
552
556 bool iterateInstructions(std::function<bool(const ShapeDefInstruction::Decoded&)> callback) const;
557
560 KnownShapeDefType recognize() const;
561
568 std::optional<Evpu> calcWidth() const;
569
574 CurveContourDirection calcSlurContour() const;
575
576 constexpr static std::string_view XmlNodeName = "shapeDef";
577 static const xml::XmlElementArray<ShapeDef>& xmlMappingArray();
578};
579
586class ShapeInstructionList : public OthersBase
587{
588public:
590 explicit ShapeInstructionList(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
591 : OthersBase(document, partId, shareMode, cmper)
592 {
593 }
594
605
606 std::vector<std::shared_ptr<InstructionInfo>> instructions;
607
608 constexpr static std::string_view XmlNodeName = "shapeList";
609 static const xml::XmlElementArray<ShapeInstructionList>& xmlMappingArray();
610};
611
612} // namespace others
613} // namespace dom
614} // 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: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:678
An instruction in the shape.
Definition ShapeDesigner.h:597
int numData
the number of data items consumed by this instruction (See ShapeData.)
Definition ShapeDesigner.h:600
static const xml::XmlElementArray< InstructionInfo > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
ShapeDefInstructionType type
the type of instruction
Definition ShapeDesigner.h:601
@ 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.
@ 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: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:57
@ 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:209
details::Bracket::BracketStyle bracketStyle
The style of bracket being created.
Definition ShapeDesigner.h:210
Holds the parsed data for a CloneChar instruction.
Definition ShapeDesigner.h:214
int baselineShift
Baseline shift in EMs (1/1000 of current point size).
Definition ShapeDesigner.h:218
int unused2
Unused/undocumented field at index 2.
Definition ShapeDesigner.h:217
char32_t codePoint
The 32-bit codepoint of the character to clone.
Definition ShapeDesigner.h:219
Evpu dy
The Y coordinate of the endpoint (currently ignored).
Definition ShapeDesigner.h:216
Evpu dx
The X coordinate of the endpoint (relative to current point).
Definition ShapeDesigner.h:215
Holds the parsed data for a CurveTo instruction.
Definition ShapeDesigner.h:223
Evpu c1dx
Relative X offset of the first control point.
Definition ShapeDesigner.h:224
Evpu c2dy
Relative Y offset of the second control point.
Definition ShapeDesigner.h:227
Evpu edy
Relative Y offset of the end point.
Definition ShapeDesigner.h:229
Evpu c2dx
Relative X offset of the second control point.
Definition ShapeDesigner.h:226
Evpu c1dy
Relative Y offset of the first control point.
Definition ShapeDesigner.h:225
Evpu edx
Relative X offset of the end point.
Definition ShapeDesigner.h:228
Contains the parsed instruction type with its data.
Definition ShapeDesigner.h:397
bool valid() const noexcept
Returns true is the data is valid.
Definition ShapeDesigner.h:402
void setPayload(std::optional< T > &&optData)
Sets the payload.
Definition ShapeDesigner.h:408
ShapeDefInstructionType type
Instruction type.
Definition ShapeDesigner.h:398
InstructionData data
Data for instruction.
Definition ShapeDesigner.h:399
Holds the parsed data for a DrawChar instruction.
Definition ShapeDesigner.h:233
char32_t codePoint
The 32-bit codepoint of the character to draw.
Definition ShapeDesigner.h:234
Holds the parsed data for an Ellipse instruction.
Definition ShapeDesigner.h:238
Evpu height
The height of the bounding rectangle.
Definition ShapeDesigner.h:240
Evpu width
The width of the bounding rectangle.
Definition ShapeDesigner.h:239
Holds the parsed data for an ExternalGraphic instruction.
Definition ShapeDesigner.h:244
Evpu height
The height of the placed graphic.
Definition ShapeDesigner.h:246
Cmper cmper
The cmper of the graphic. See others::PageGraphicAssign::graphicCmper for explanation.
Definition ShapeDesigner.h:247
Evpu width
The width of the placed graphic.
Definition ShapeDesigner.h:245
Holds the parsed data for a LineWidth instruction.
Definition ShapeDesigner.h:251
Efix efix
The line width in Efix units.
Definition ShapeDesigner.h:252
Holds the parsed data for an RLineTo instruction.
Definition ShapeDesigner.h:262
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:263
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:264
Holds the parsed data for an RMoveTo instruction.
Definition ShapeDesigner.h:268
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:269
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:270
Holds the parsed data for a Rectangle instruction.
Definition ShapeDesigner.h:256
Evpu height
The height of the rectangle.
Definition ShapeDesigner.h:258
Evpu width
The width of the rectangle.
Definition ShapeDesigner.h:257
Holds the parsed data for a SetArrowhead instruction.
Definition ShapeDesigner.h:274
int startArrowId
Raw word 1. Start arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:276
int extra
Raw word 3. Unknown (value persists when edited by plugin; no observed rendering effect in current ex...
Definition ShapeDesigner.h:278
int endKindCode() const noexcept
Returns the end kind code from packedKindCodes (high 16 bits).
Definition ShapeDesigner.h:285
int endArrowId
Raw word 2. End arrowhead id (preset id or custom arrowhead ShapeDef cmper).
Definition ShapeDesigner.h:277
int startKindCode() const noexcept
Returns the start kind code from packedKindCodes (low 16 bits).
Definition ShapeDesigner.h:281
int packedKindCodes
Raw word 0. Packs start/end kind codes (e.g. 0x00010001 preset/preset, 0x00020002 custom/custom).
Definition ShapeDesigner.h:275
Holds the parsed data for a SetDash instruction.
Definition ShapeDesigner.h:290
Evpu spaceLength
Space between dashes in Evpu.
Definition ShapeDesigner.h:292
Evpu dashLength
Length of each dash segment in Evpu.
Definition ShapeDesigner.h:291
Holds the parsed data for a SetFont instruction.
Definition ShapeDesigner.h:296
SetFont(const DocumentWeakPtr &document)
Constructor function.
Definition ShapeDesigner.h:298
FontInfo font
the parsed font
Definition ShapeDesigner.h:300
Holds the parsed data for a SetGray instruction.
Definition ShapeDesigner.h:304
int gray
Gray value between 0 (black) and 100 (white).
Definition ShapeDesigner.h:305
Holds the parsed data for a Slur instruction.
Definition ShapeDesigner.h:311
Evpu16ths edx
Relative X offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:316
Evpu16ths c2dx
Relative X offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:314
Evpu16ths c1dx
Relative X offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:312
Evpu16ths c2dy
Relative Y offset of the second control point (1/16 Evpu units).
Definition ShapeDesigner.h:315
Evpu16ths edy
Relative Y offset of the end point (1/16 Evpu units).
Definition ShapeDesigner.h:317
Evpu16ths c1dy
Relative Y offset of the first control point (1/16 Evpu units).
Definition ShapeDesigner.h:313
Holds the parsed data for a StartGroup instruction.
Definition ShapeDesigner.h:340
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:346
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:342
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:354
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:348
int rotation
Definition ShapeDesigner.h:349
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:344
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:345
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:353
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:347
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:343
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:341
Holds the parsed data for a StartObject instruction.
Definition ShapeDesigner.h:321
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:324
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:323
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:327
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:329
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:335
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:328
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:325
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:334
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:322
int rotation
Definition ShapeDesigner.h:330
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:326
Holds the parsed data for an Undocumented instruction.
Definition ShapeDesigner.h:204
std::vector< int > data
Raw data items for the undocumented instruction.
Definition ShapeDesigner.h:205
Holds the parsed data for a VerticalMode instruction.
Definition ShapeDesigner.h:365
VerticalAlign mode
The pen vertical alignment mode.
Definition ShapeDesigner.h:366
Helper functions and structs for decoding instruction data vectors in others::ShapeDef.
Definition ShapeDesigner.h:201
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:358
@ 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:392
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