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
39{
40 Blank,
42
43 // Add more known types here
44};
45
49{
52
57 Bracket,
58
66
70
73 CurveTo,
74
78
82 Ellipse,
83
87
91
94 FillAlt,
95
99
103
106 GoToStart,
107
110 LineWidth,
111
115 Rectangle,
116
119 RLineTo,
120
123 RMoveTo,
124
129
132 SetBlack,
133
136 SetDash,
137
140 SetFont,
141
144 SetGray,
145
148 SetWhite,
149
153 Slur,
154
158
167
170 Stroke,
171
176};
177
181{
185 std::vector<int> data;
186 };
187
192
201
211
213 struct DrawChar {
214 char32_t codePoint;
215 };
216
222
229
231 struct LineWidth {
233 };
234
240
242 struct RLineTo {
245 };
246
248 struct RMoveTo {
251 };
252
260
266
268 struct SetFont {
270 SetFont(const DocumentWeakPtr& document) : font(document)
271 {}
273 };
274
276 struct SetGray {
277 int gray;
278 };
279
290
305
321
323 enum class VerticalAlign {
324 Center = 1,
325 Left = 2,
326 Right = 3
327 };
328
333
334
336 using InstructionData = std::variant<
337 std::monostate, // for commands with no data
339 Bracket,
340 CloneChar,
341 CurveTo,
342 DrawChar,
343 Ellipse,
345 LineWidth,
346 Rectangle,
347 RLineTo,
348 RMoveTo,
350 SetDash,
351 SetFont,
352 SetGray,
353 Slur,
357 >;
358
361 struct Decoded
362 {
364 InstructionData data{std::monostate{}};
365
367 bool valid() const noexcept { return m_valid; }
368
372 template <typename T>
373 void setPayload(std::optional<T>&& optData)
374 {
375 if (optData) {
376 // Move the contained T into the variant
377 data = std::move(*optData);
378 m_valid = true;
379 } else {
380 // We *tried* to parse data and failed
381 m_valid = false;
382 }
383 }
384
385 private:
386 bool m_valid{true};
387 };
388
390 static std::optional<Undocumented> parseUndocumented(const std::vector<int>& data);
391
393 static std::optional<Bracket> parseBracket(const std::vector<int>& data);
394
396 static std::optional<CloneChar> parseCloneChar(const std::vector<int>& data);
397
399 static std::optional<CurveTo> parseCurveTo(const std::vector<int>& data);
400
402 static std::optional<DrawChar> parseDrawChar(const std::vector<int>& data);
403
405 static std::optional<Ellipse> parseEllipse(const std::vector<int>& data);
406
408 static std::optional<ExternalGraphic> parseExternalGraphic(const std::vector<int>& data);
409
411 static std::optional<LineWidth> parseLineWidth(const std::vector<int>& data);
412
414 static std::optional<Rectangle> parseRectangle(const std::vector<int>& data);
415
417 static std::optional<RLineTo> parseRLineTo(const std::vector<int>& data);
418
420 static std::optional<RMoveTo> parseRMoveTo(const std::vector<int>& data);
421
423 static std::optional<SetArrowhead> parseSetArrowhead(const std::vector<int>& data);
424
426 static std::optional<SetDash> parseSetDash(const std::vector<int>& data);
427
429 static std::optional<SetFont> parseSetFont(const DocumentWeakPtr& document, const std::vector<int>& data);
430
432 static std::optional<SetGray> parseSetGray(const std::vector<int>& data);
433
435 static std::optional<Slur> parseSlur(const std::vector<int>& data);
436
438 static std::optional<StartGroup> parseStartGroup(const std::vector<int>& data);
439
441 static std::optional<StartObject> parseStartObject(const std::vector<int>& data);
442
444 static std::optional<VerticalMode> parseVerticalMode(const std::vector<int>& data);
445};
446
447namespace others {
448
455class ShapeData : public OthersArray<int>
456{
457 std::string_view xmlTag() const override { return XmlNodeName; }
458
459public:
461
462 constexpr static std::string_view XmlNodeName = "shapeData";
463 static const xml::XmlElementArray<ShapeData>& xmlMappingArray();
464};
465
466#ifndef DOXYGEN_SHOULD_IGNORE_THIS
467class ShapeDefTestAccessor; // used by tests to access private iterator in ShapeDef
468#endif
469
470class ShapeInstructionList;
477class ShapeDef : public OthersBase
478{
479private:
481 bool iterateInstructions(std::function<bool(ShapeDefInstructionType, std::vector<int>)> callback) const;
482
483 friend class ShapeDefTestAccessor; // gives tests access, but users don't see it
484
485public:
487 explicit ShapeDef(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
488 : OthersBase(document, partId, shareMode, cmper)
489 {
490 }
491
496 enum class ShapeType
497 {
498 Other = 0,
499 Articulation = 1,
500 Barline = 2,
501 Executable = 3,
502 Expression = 4,
503 CustomStem = 5,
504 Frame = 6,
505 Arrowhead = 7,
506 Fretboard = 8,
507 Clef = 9
508 };
509
510 Cmper instructionList;
511 Cmper dataList;
512 ShapeType shapeType;
513
515 bool isBlank() const
516 { return instructionList == 0; }
517
521 bool iterateInstructions(std::function<bool(const ShapeDefInstruction::Decoded&)> callback) const;
522
523
526 std::optional<KnownShapeDefType> recognize() const;
527
528 constexpr static std::string_view XmlNodeName = "shapeDef";
529 static const xml::XmlElementArray<ShapeDef>& xmlMappingArray();
530};
531
538class ShapeInstructionList : public OthersBase
539{
540public:
542 explicit ShapeInstructionList(const DocumentWeakPtr& document, Cmper partId, ShareMode shareMode, Cmper cmper)
543 : OthersBase(document, partId, shareMode, cmper)
544 {
545 }
546
557
558 std::vector<std::shared_ptr<InstructionInfo>> instructions;
559
560 constexpr static std::string_view XmlNodeName = "shapeList";
561 static const xml::XmlElementArray<ShapeInstructionList>& xmlMappingArray();
562};
563
564} // namespace others
565} // namespace dom
566} // 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:126
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:628
An instruction in the shape.
Definition ShapeDesigner.h:549
int numData
the number of data items consumed by this instruction (See ShapeData.)
Definition ShapeDesigner.h:552
static const xml::XmlElementArray< InstructionInfo > & xmlMappingArray()
Required for musx::factory::FieldPopulator.
ShapeDefInstructionType type
the type of instruction
Definition ShapeDesigner.h:553
@ Other
Other/unknown text encoding.
KnownShapeDefType
Enumerates the shape types we can recognize semantically.
Definition ShapeDesigner.h:39
@ TenutoMark
A horizontal tenuto mark, typically used as an articulation symbol.
int32_t Efix
EFIX value (64 per EVPU, 64*288=18432 per inch)
Definition Fundamentals.h:60
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:49
@ 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:189
details::Bracket::BracketStyle bracketStyle
The style of bracket being created.
Definition ShapeDesigner.h:190
Holds the parsed data for a CloneChar instruction.
Definition ShapeDesigner.h:194
int baselineShift
Baseline shift in EMs (1/1000 of current point size).
Definition ShapeDesigner.h:198
int unused2
Unused/undocumented field at index 2.
Definition ShapeDesigner.h:197
char32_t codePoint
The 32-bit codepoint of the character to clone.
Definition ShapeDesigner.h:199
Evpu dy
The Y coordinate of the endpoint (currently ignored).
Definition ShapeDesigner.h:196
Evpu dx
The X coordinate of the endpoint (relative to current point).
Definition ShapeDesigner.h:195
Holds the parsed data for a CurveTo instruction.
Definition ShapeDesigner.h:203
Evpu c1dx
Relative X offset of the first control point.
Definition ShapeDesigner.h:204
Evpu c2dy
Relative Y offset of the second control point.
Definition ShapeDesigner.h:207
Evpu edy
Relative Y offset of the end point.
Definition ShapeDesigner.h:209
Evpu c2dx
Relative X offset of the second control point.
Definition ShapeDesigner.h:206
Evpu c1dy
Relative Y offset of the first control point.
Definition ShapeDesigner.h:205
Evpu edx
Relative X offset of the end point.
Definition ShapeDesigner.h:208
Contains the parsed instruction type with its data.
Definition ShapeDesigner.h:362
bool valid() const noexcept
Returns true is the data is valid.
Definition ShapeDesigner.h:367
void setPayload(std::optional< T > &&optData)
Sets the payload.
Definition ShapeDesigner.h:373
ShapeDefInstructionType type
Instruction type.
Definition ShapeDesigner.h:363
InstructionData data
Data for instruction.
Definition ShapeDesigner.h:364
Holds the parsed data for a DrawChar instruction.
Definition ShapeDesigner.h:213
char32_t codePoint
The 32-bit codepoint of the character to draw.
Definition ShapeDesigner.h:214
Holds the parsed data for an Ellipse instruction.
Definition ShapeDesigner.h:218
Evpu height
The height of the bounding rectangle.
Definition ShapeDesigner.h:220
Evpu width
The width of the bounding rectangle.
Definition ShapeDesigner.h:219
Holds the parsed data for an ExternalGraphic instruction.
Definition ShapeDesigner.h:224
Evpu height
The height of the placed graphic.
Definition ShapeDesigner.h:226
Cmper cmper
The cmper of the graphic. See others::PageGraphicAssign::graphicCmper for explanation.
Definition ShapeDesigner.h:227
Evpu width
The width of the placed graphic.
Definition ShapeDesigner.h:225
Holds the parsed data for a LineWidth instruction.
Definition ShapeDesigner.h:231
Efix efix
The line width in Efix units.
Definition ShapeDesigner.h:232
Holds the parsed data for an RLineTo instruction.
Definition ShapeDesigner.h:242
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:243
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:244
Holds the parsed data for an RMoveTo instruction.
Definition ShapeDesigner.h:248
Evpu dx
The relative X coordinate delta in Evpu.
Definition ShapeDesigner.h:249
Evpu dy
The relative Y coordinate delta in Evpu.
Definition ShapeDesigner.h:250
Holds the parsed data for a Rectangle instruction.
Definition ShapeDesigner.h:236
Evpu height
The height of the rectangle.
Definition ShapeDesigner.h:238
Evpu width
The width of the rectangle.
Definition ShapeDesigner.h:237
Holds the parsed data for a SetArrowhead instruction.
Definition ShapeDesigner.h:254
int endFlags
Flags for the end arrowhead (built-in vs custom, etc.).
Definition ShapeDesigner.h:258
int startArrowId
Identifier of the start arrowhead.
Definition ShapeDesigner.h:255
int startFlags
Flags for the start arrowhead (built-in vs custom, etc.).
Definition ShapeDesigner.h:257
int endArrowId
Identifier of the end arrowhead.
Definition ShapeDesigner.h:256
Holds the parsed data for a SetDash instruction.
Definition ShapeDesigner.h:262
Efix dashLength
Length of each dash segment.
Definition ShapeDesigner.h:263
Efix spaceLength
Space between dashes.
Definition ShapeDesigner.h:264
Holds the parsed data for a SetFont instruction.
Definition ShapeDesigner.h:268
SetFont(const DocumentWeakPtr &document)
Constructor function.
Definition ShapeDesigner.h:270
FontInfo font
the parsed font
Definition ShapeDesigner.h:272
Holds the parsed data for a SetGray instruction.
Definition ShapeDesigner.h:276
int gray
Gray value between 0 (black) and 100 (white).
Definition ShapeDesigner.h:277
Holds the parsed data for a Slur instruction.
Definition ShapeDesigner.h:282
Evpu edx
Relative X offset of the end point.
Definition ShapeDesigner.h:287
Evpu c2dx
Relative X offset of the second control point.
Definition ShapeDesigner.h:285
Evpu c2dy
Relative Y offset of the second control point.
Definition ShapeDesigner.h:286
Evpu edy
Relative Y offset of the end point.
Definition ShapeDesigner.h:288
Evpu c1dy
Relative Y offset of the first control point.
Definition ShapeDesigner.h:284
Evpu c1dx
Relative X offset of the first control point.
Definition ShapeDesigner.h:283
Holds the parsed data for a StartGroup instruction.
Definition ShapeDesigner.h:308
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:314
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:310
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:319
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:316
int rotation
Rotation transform.
Definition ShapeDesigner.h:317
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:312
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:313
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:318
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:315
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:311
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:309
Holds the parsed data for a StartObject instruction.
Definition ShapeDesigner.h:292
Evpu left
Left of the bounding rectangle.
Definition ShapeDesigner.h:295
Evpu originY
Y coordinate of the origin point.
Definition ShapeDesigner.h:294
Evpu bottom
Bottom of the bounding rectangle.
Definition ShapeDesigner.h:298
int scaleY
Y scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:300
int unused10
Undocumented/unused field at index 10.
Definition ShapeDesigner.h:303
int scaleX
X scale transform (scale ratio * 1000).
Definition ShapeDesigner.h:299
Evpu top
Top of the bounding rectangle.
Definition ShapeDesigner.h:296
int unused9
Undocumented/unused field at index 9.
Definition ShapeDesigner.h:302
Evpu originX
X coordinate of the origin point.
Definition ShapeDesigner.h:293
int rotation
Rotation transform.
Definition ShapeDesigner.h:301
Evpu right
Right of the bounding rectangle.
Definition ShapeDesigner.h:297
Holds the parsed data for an Undocumented instruction.
Definition ShapeDesigner.h:184
std::vector< int > data
Raw data items for the undocumented instruction.
Definition ShapeDesigner.h:185
Holds the parsed data for a VerticalMode instruction.
Definition ShapeDesigner.h:330
VerticalAlign mode
The pen vertical alignment mode.
Definition ShapeDesigner.h:331
Helper functions and structs for decoding instruction data vectors in others::ShapeDef.
Definition ShapeDesigner.h:181
static std::optional< SetFont > parseSetFont(const DocumentWeakPtr &document, const std::vector< int > &data)
Attempts to parse a SetFont instruction.
Definition ShapeDesigner.cpp:201
static std::optional< ExternalGraphic > parseExternalGraphic(const std::vector< int > &data)
Attempts to parse an ExternalGraphic instruction.
Definition ShapeDesigner.cpp:120
static std::optional< Slur > parseSlur(const std::vector< int > &data)
Attempts to parse a Slur instruction.
Definition ShapeDesigner.cpp:225
static std::optional< LineWidth > parseLineWidth(const std::vector< int > &data)
Attempts to parse a LineWidth instruction.
Definition ShapeDesigner.cpp:133
static std::optional< VerticalMode > parseVerticalMode(const std::vector< int > &data)
Attempts to parse a VerticalMode instruction.
Definition ShapeDesigner.cpp:280
static std::optional< SetGray > parseSetGray(const std::vector< int > &data)
Attempts to parse a SetGray instruction.
Definition ShapeDesigner.cpp:214
static std::optional< DrawChar > parseDrawChar(const std::vector< int > &data)
Attempts to parse a DrawChar instruction.
Definition ShapeDesigner.cpp:99
static std::optional< StartObject > parseStartObject(const std::vector< int > &data)
Attempts to parse a StartObject instruction.
Definition ShapeDesigner.cpp:259
VerticalAlign
Pen vertical alignment modes for the VerticalMode instruction.
Definition ShapeDesigner.h:323
@ 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:175
static std::optional< StartGroup > parseStartGroup(const std::vector< int > &data)
Attempts to parse a StartGroup instruction.
Definition ShapeDesigner.cpp:238
static std::optional< Rectangle > parseRectangle(const std::vector< int > &data)
Attempts to parse a Rectangle instruction.
Definition ShapeDesigner.cpp:142
static std::optional< RLineTo > parseRLineTo(const std::vector< int > &data)
Attempts to parse an RLineTo instruction.
Definition ShapeDesigner.cpp:154
static std::optional< RMoveTo > parseRMoveTo(const std::vector< int > &data)
Attempts to parse an RMoveTo instruction.
Definition ShapeDesigner.cpp:163
static std::optional< Ellipse > parseEllipse(const std::vector< int > &data)
Attempts to parse an Ellipse instruction.
Definition ShapeDesigner.cpp:108
static std::optional< SetDash > parseSetDash(const std::vector< int > &data)
Attempts to parse a SetDash instruction.
Definition ShapeDesigner.cpp:189
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:357
static std::optional< CloneChar > parseCloneChar(const std::vector< int > &data)
Attempts to parse a CloneChar instruction.
Definition ShapeDesigner.cpp:71
static std::optional< CurveTo > parseCurveTo(const std::vector< int > &data)
Attempts to parse a CurveTo instruction.
Definition ShapeDesigner.cpp:86
static std::optional< Undocumented > parseUndocumented(const std::vector< int > &data)
Attempts to parse an Undocumented instruction (raw passthrough).
Definition ShapeDesigner.cpp:37
static std::optional< Bracket > parseBracket(const std::vector< int > &data)
Attempts to parse a Bracket instruction.
Definition ShapeDesigner.cpp:44