& triggers)
296 | {
297 | // Loop through triggers
298 | for (unsigned int i = 0; i < triggers.size(); i++)
299 | {
300 | // Convenient reference
301 | Trigger* trigger = triggers[i];
302 |
303 | // Try to resolve
304 | Function* function = nullptr;
305 | if (ResolveTriggerFunction(*trigger, &function))
306 | {
307 | // Bind
308 | if (function->type == Function::kDrawFunction)
309 | {
310 | // TODO: Should this be the "used" name?
311 | trigger->sourceObject = function->name;
312 | }
313 | else if (function->type == Function::kAnimationFunction)
314 | {
315 | stringstream animation;
316 | animation << "animations[" << ((AnimationFunction*)function)->index << "]";
317 | trigger->sourceObject = animation.str();
318 | }
319 | trigger->parsedOkay = true;
320 | }
321 | else
322 | {
323 | // Can't bind
324 | // TODO: Should we just remove it?
325 | trigger->parsedOkay = false;
326 | }
327 | }
328 | }
329 |
330 | // Pass in a trigger, resolves function and animation clock
331 | // Returns true if successful, false if not
332 | bool FunctionCollection::ResolveTriggerFunction(Trigger& trigger, Function** function)
333 | {
334 | // Default return value
335 | bool result = false;
336 |
337 | // Is this an animation function?
338 | Function* searchFunction = nullptr;
339 | searchFunction = Find(trigger.sourceObject, Function::kAnimationFunction);
340 |
341 | // Find anything?
342 | if (searchFunction != nullptr)
343 | {
344 | // Return function
345 | *function = searchFunction;
346 |
347 | // Clock name should be empty, since there's only one clock on an animation function
348 | if (trigger.sourceClock.empty())
349 | {
350 | // Path clock
351 | trigger.sourceClock = "pathClock";
352 |
353 | // Note a successful resolution
354 | result = true;
355 | }
356 | }
357 | else
358 | {
359 | // Is this a draw function?
360 | bool isLast = false;
361 | searchFunction = FindDrawFunction(trigger.sourceObject, isLast);
362 |
363 | // Find anything?
364 | if (searchFunction != nullptr)
365 | {
366 | // Return function
367 | *function = searchFunction;
368 |
369 | // Resolve clock names
370 | if (trigger.sourceClock == "rotate" ||
371 | trigger.sourceClock == "r")
372 | {
373 | // Rotate clock
374 | trigger.sourceClock = "rotateClock";
375 |
376 | // Note a successful resolution
377 | result = true;
378 | }
379 | else if (trigger.sourceClock == "scale" ||
380 | trigger.sourceClock == "s")
381 | {
382 | // Scale clock
383 | trigger.sourceClock = "scaleClock";
384 |
385 | // Note a successful resolution
386 | result = true;
387 | }
388 | else if (trigger.sourceClock == "alpha" ||
389 | trigger.sourceClock == "a")
390 | {
391 | // Alpha clock
392 | trigger.sourceClock = "alphaClock";
393 |
394 | // Note a successful resolution
395 | result = true;
396 | }
397 | }
398 | }
399 |
400 | return result;
401 | }
402 |
403 |
404 | // Do the functions have any valid clock triggers?
405 | bool const FunctionCollection::HasValidTriggers()
406 | {
407 | bool result = false;
408 |
409 | for (unsigned int i = 0; i < functions.size(); i++)
410 | {
411 | if (functions[i]->HasValidTriggers())
412 | {
413 | // Found at least one
414 | result = true;
415 | break;
416 | }
417 | }
418 |
419 | return result;
420 | }
421 |
422 | Function* FunctionCollection::Find(const std::string& name, const Function::FunctionType& functionType)
423 | {
424 | Function* function = nullptr;
425 |
426 | // Any functions to search?
427 | size_t i = functions.size();
428 | if (i > 0)
429 | {
430 | // Loop through functions
431 | do
432 | {
433 | i--;
434 |
435 | // Correct type?
436 | if ((functions[i]->type == functionType) ||
437 | (functions[i]->type == Function::kAnyFunction))
438 | {
439 | // Do the names match?
440 | if (functions[i]->name == name)
441 | {
442 | // Found a match
443 | function = functions[i];
444 | break;
445 | }
446 | }
447 | } while (i > 0);
448 | }
449 |
450 | // Return result
451 | return function;
452 | }
453 |
454 | // Returns a unique function name (which could be identical to what was passed in, if it's unique)
455 | std::string FunctionCollection::CreateUniqueName(const std::string& name)
456 | {
457 | // Since we may change the name, copy it first
458 | std::string usedName = name;
459 |
460 | // Does a function with this name already exist?
461 | Function* function = Find(usedName, Function::kAnyFunction);
462 |
463 | // Did we find anything?
464 | if (function)
465 | {
466 | // Find a unique name
467 | std::ostringstream uniqueName;
468 | int unique = 0;
469 | do
470 | {
471 | // Increment to make unique name
472 | unique++;
473 |
474 | // Generate a unique name
475 | uniqueName.str("");
476 | uniqueName << usedName << unique;
477 | } while (Find(uniqueName.str(), Function::kAnyFunction));
478 |
479 | // Assign unique name
480 | usedName = uniqueName.str();
481 | }
482 |
483 | // Return the unique name
484 | return usedName;
485 | }
486 |
487 | // Adds a new animation function
488 | DrawFunction* FunctionCollection::AddDrawFunction(const std::string& name)
489 | {
490 | // Since we may change the name, copy it first
491 | std::string uniqueName = name;
492 |
493 | // Does a function with this name already exist?
494 | bool isLast = false;
495 | DrawFunction* drawFunction = FindDrawFunction(uniqueName, isLast);
496 |
497 | // Did we find the function?
498 | if (drawFunction)
499 | {
500 | // We found the function. Is it the most recent drawing function we've added (don't consider animation layers)?
501 | // Since drawing order is bottoms-up, we can't "go back to" a prior function and add layers to it...it must be unique at that point
502 | if (!isLast)
503 | {
504 | // It's not the most recent function, so we have to make it unique
505 |
506 | // Need a new function
507 | drawFunction = nullptr;
508 |
509 | // Generate unique name
510 | uniqueName = CreateUniqueName(uniqueName);
511 | }
512 | }
513 | else
514 | {
515 | // Matched another function type (perhaps animation), so we need a unique name
516 | uniqueName = CreateUniqueName(uniqueName);
517 | }
518 |
519 | // Do we have a function yet?
520 | if (!drawFunction)
521 | {
522 | // Create a new function
523 | drawFunction = new DrawFunction();
524 |
525 | // Assign names
526 | drawFunction->requestedName = name;
527 | drawFunction->name = uniqueName;
528 |
529 | // Add function
530 | functions.push_back(drawFunction);
531 |
532 | // Note that we have at least one draw function in the collection
533 | hasDrawFunctions = true;
534 | }
535 |
536 | // Return the function
537 | return drawFunction;
538 | }
539 |
540 | // Find a draw function
541 | // TODO: Any way we can clean this up? Seems a bit convoluted.
542 | DrawFunction* FunctionCollection::FindDrawFunction(const std::string& name, bool& isLast)
543 | {
544 | DrawFunction* drawFunction = nullptr;
545 |
546 | // By default
547 | isLast = false;
548 |
549 | // Track if we've seen a draw function yet
550 | bool passedDrawFunction = false;
551 |
552 | // Any functions to search?
553 | size_t i = functions.size();
554 | if (i > 0)
555 | {
556 | // Loop through functions
557 | do
558 | {
559 | i--;
560 |
561 | if (functions[i]->type == Function::kDrawFunction)
562 | {
563 | // Cast to DrawFunction
564 | DrawFunction* searchDrawFunction = (DrawFunction*)functions[i];
565 |
566 | // Do the names match?
567 | if ((searchDrawFunction->name == name) ||
568 | (searchDrawFunction->requestedName == name))
569 | {
570 | // Found a match
571 | drawFunction = searchDrawFunction;
572 | break;
573 | }
574 |
575 | // Can't be the last, if we've made it here
576 | passedDrawFunction = true;
577 | }
578 | } while (i > 0);
579 |
580 | // Did we find something AND it's the last draw function?
581 | if (drawFunction && (!passedDrawFunction))
582 | {
583 | isLast = true;
584 | }
585 | }
586 |
587 | // Return result
588 | return drawFunction;
589 | }
590 |
591 | // Adds a new animation function
592 | AnimationFunction* FunctionCollection::AddAnimationFunction(const std::string& name)
593 | {
594 | // Since we may change the name, copy it first
595 | std::string usedName = name;
596 |
597 | // Does a function with this name already exist?
598 | Function* function = Find(usedName, Function::kAnyFunction);
599 |
600 | // Did we find anything?
601 | if (function)
602 | {
603 | // Find a unique name
604 | std::ostringstream uniqueName;
605 | int unique = 0;
606 | do
607 | {
608 | // Increment to make unique name
609 | unique++;
610 |
611 | // Generate a unique name
612 | uniqueName.str("");
613 | uniqueName << unique;
614 | } while (Find(uniqueName.str(), Function::kAnyFunction));
615 |
616 | // Assign unique name
617 | usedName = uniqueName.str();
618 | }
619 |
620 | // Now that we have a unique name, create a new animation function
621 | AnimationFunction* animationFunction = new AnimationFunction();
622 |
623 | // Assign properties
624 | animationFunction->name = usedName;
625 | animationFunction->index = animationIndex;
626 |
627 | // Increment index
628 | animationIndex++;
629 |
630 | // Add it to the functions array
631 | functions.push_back(animationFunction);
632 |
633 | // Note that we have at least one animation function in the collection
634 | hasAnimationFunctions = true;
635 |
636 | // Return new animation function
637 | return animationFunction;
638 | }
639 |
640 | void FunctionCollection::DebugInfo()
641 | {
642 | // Gather info
643 | unsigned int drawFunctionCount = 0;
644 | unsigned int animationFunctionCount = 0;
645 |
646 | // Loop through functions
647 | for (unsigned int i = 0; i < functions.size(); i++)
648 | {
649 | switch (functions[i]->type)
650 | {
651 | case Function::kAnimationFunction:
652 | {
653 | ++animationFunctionCount;
654 | break;
655 | }
656 | case Function::kDrawFunction:
657 | {
658 | ++drawFunctionCount;
659 | break;
660 | }
661 | case Function::kAnyFunction:
662 | {
663 | break;
664 | }
665 | }
666 | }
667 |
668 | // Animation function debug info
669 | outFile << "\nAnimation functions: " << animationFunctionCount << "
";
670 |
671 | // Anything to list?
672 | if (animationFunctionCount > 0)
673 | {
674 | // Start unordered list
675 | outFile << "\n";
676 |
677 | // Loop through each animation function
678 | for (unsigned int i = 0; i < functions.size(); i++)
679 | {
680 | if (functions[i]->type == Function::kAnimationFunction)
681 | {
682 | // For convenience
683 | AnimationFunction* animationFunction = (AnimationFunction*)functions[i];
684 |
685 | outFile << "\n - name: " << animationFunction->name << ", index: " << animationFunction->index <<
686 | ", segments: " << animationFunction->beziers.size() <<
687 | ", linear segment length: " << setiosflags(ios::fixed) << setprecision(1) << animationFunction->segmentLength << "
";
688 | }
689 | }
690 |
691 | // End unordered list
692 | outFile << "\n
";
693 | }
694 |
695 | // Draw function debug info
696 | outFile << "\nDraw functions: " << drawFunctionCount << "
";
697 |
698 | // Anything to list?
699 | if (drawFunctionCount > 0)
700 | {
701 | // Start unordered list
702 | outFile << "\n";
703 |
704 | // Loop through each draw function
705 | for (unsigned int i = 0; i < functions.size(); i++)
706 | {
707 | if (functions[i]->type == Function::kDrawFunction)
708 | {
709 | // For convenience
710 | DrawFunction* drawFunction = (DrawFunction*)functions[i];
711 |
712 | outFile << "\n - name: " << drawFunction->name << ", layers: " << drawFunction->layers.size() << "
";
713 | }
714 | }
715 |
716 | // End unordered list
717 | outFile << "\n
";
718 | }
719 | }
720 |
--------------------------------------------------------------------------------
/Source/FunctionCollection.h:
--------------------------------------------------------------------------------
1 | // FunctionCollection.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef FUNCTIONCOLLECTION_H
24 | #define FUNCTIONCOLLECTION_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Function.h"
28 | #include "AnimationFunction.h"
29 | #include "DrawFunction.h"
30 | #include "Utility.h"
31 |
32 | namespace CanvasExport
33 | {
34 | // Globals
35 | extern ofstream outFile;
36 | extern bool debug;
37 |
38 | /// Represents a collection of functions
39 | class FunctionCollection
40 | {
41 | private:
42 |
43 | unsigned int animationIndex; // Track JavaScript array index for animation functions
44 | bool hasAnimationFunctions; // Does the collection include at least one animation function?
45 | bool hasDrawFunctions; // Does the collection include at least one draw function?
46 |
47 | public:
48 |
49 | FunctionCollection();
50 | ~FunctionCollection();
51 |
52 | std::vector functions; // Collection of functions
53 |
54 | bool const HasAnimationFunctions();
55 | bool const HasDrawFunctions();
56 | bool const HasDrawFunctionAnimation();
57 | Function* Find(const std::string& name, const Function::FunctionType& functionType);
58 | std::string CreateUniqueName(const std::string& name);
59 | DrawFunction* AddDrawFunction(const std::string& name);
60 | DrawFunction* FindDrawFunction(const std::string& name, bool& isLast);
61 | AnimationFunction* AddAnimationFunction(const std::string& name);
62 | bool const HasValidTriggers();
63 |
64 | void RenderClockInit();
65 | void RenderClockStart();
66 | void RenderClockTick();
67 | void RenderDrawFunctionCalls(const AIRealRect& documentBounds);
68 | void RenderDrawFunctions(const AIRealRect& documentBounds);
69 | void RenderAnimationFunctionInits(const AIRealRect& documentBounds);
70 |
71 | void BindAnimationFunctions();
72 | void BindTriggers();
73 | void ResolveTriggers(std::vector& triggers);
74 | bool ResolveTriggerFunction(Trigger& trigger, Function** function);
75 | void DebugInfo();
76 |
77 | };
78 | }
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/Source/Image.cpp:
--------------------------------------------------------------------------------
1 | // Image.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "Image.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | Image::Image(const std::string& id, const std::string& path)
29 | {
30 | // Initialize Image
31 | this->id = id;
32 | this->path = path;
33 | this->name = "";
34 | this->pathIsAbsolute = false;
35 | }
36 |
37 | Image::~Image()
38 | {
39 | }
40 |
41 | void Image::Render()
42 | {
43 | // Output image tag
44 | outFile << "\n
";
45 | }
46 |
47 | std::string Image::Uri()
48 | {
49 | // Create file URI
50 | ai::UnicodeString usPath(path);
51 | ai::FilePath aiFilePath(usPath);
52 | std::string uri = aiFilePath.GetAsURL(false).as_Platform();
53 |
54 | // Firefox doesn't like local "file:" references
55 | if (!pathIsAbsolute && uri.length() >= 5 && uri.substr(0, 5) == "file:")
56 | {
57 | // Strip "file:" from string
58 | uri = uri.substr(5);
59 | }
60 |
61 | // Initial slashes?
62 | if (!pathIsAbsolute && uri.length() >= 3 && uri.substr(0, 3) == "///")
63 | {
64 | // Strip "///" from string
65 | uri = uri.substr(3);
66 | }
67 |
68 | return uri;
69 | }
70 |
71 | void Image::RenderDrawImage(const std::string& contextName, const AIReal x, const AIReal y)
72 | {
73 | // Draw image
74 | outFile << "\n" << Indent(0) << contextName << ".drawImage(document.getElementById(\"" << id << "\"), " <<
75 | setiosflags(ios::fixed) << setprecision(1) <<
76 | x << ", " << y << ");";
77 | }
78 |
79 | void Image::DebugBounds(const std::string& contextName, const AIRealRect& bounds)
80 | {
81 | if (debug)
82 | {
83 | // Stroke bounds
84 | outFile << "\n" << Indent(0) << contextName << ".save();";
85 | outFile << "\n" << Indent(0) << contextName << ".lineWidth = 1.0;";
86 | outFile << "\n" << Indent(0) << contextName << ".strokeStyle = \"rgb(255, 0, 0)\";";
87 | outFile << "\n" << Indent(0) << contextName << ".strokeRect(" <<
88 | setiosflags(ios::fixed) << setprecision(1) <<
89 | bounds.left << ", " << bounds.top << ", " << (bounds.right - bounds.left) << ", " << (bounds.bottom - bounds.top) << ");";
90 | outFile << "\n" << Indent(0) << contextName << ".restore();";
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Source/Image.h:
--------------------------------------------------------------------------------
1 | // Image.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef IMAGE_H
24 | #define IMAGE_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Utility.h"
28 |
29 | namespace CanvasExport
30 | {
31 | // Globals
32 | extern ofstream outFile;
33 | extern bool debug;
34 |
35 | /// Represents a bitmap image
36 | class Image
37 | {
38 | private:
39 |
40 |
41 | public:
42 |
43 | Image(const std::string& id, const std::string& path);
44 | ~Image();
45 |
46 | std::string id; // Image element ID
47 | std::string path; // File path to the image
48 | std::string name; // Name of the image (to be used for the alt attribute)
49 | bool pathIsAbsolute; // Is this an absolute image path?
50 |
51 | void Render();
52 | void RenderDrawImage(const std::string& contextName, const AIReal x, const AIReal y);
53 | void DebugBounds(const std::string& contextName, const AIRealRect& bounds);
54 | std::string Uri();
55 |
56 | };
57 | }
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/Source/ImageCollection.cpp:
--------------------------------------------------------------------------------
1 | // ImageCollection.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "ImageCollection.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | ImageCollection::ImageCollection()
29 | {
30 | }
31 |
32 | ImageCollection::~ImageCollection()
33 | {
34 | // Clear images
35 | for (unsigned int i = 0; i < images.size(); i++)
36 | {
37 | // Remove instance
38 | delete images[i];
39 | }
40 | }
41 |
42 | void ImageCollection::Render()
43 | {
44 | // Render images
45 | for (unsigned int i = 0; i < images.size(); i++)
46 | {
47 | // Render
48 | images[i]->Render();
49 | }
50 | }
51 |
52 | // Won't add an image if it already exists
53 | Image* ImageCollection::Add(const std::string& path)
54 | {
55 | // Does this image already exist?
56 | Image* image = Find(path);
57 |
58 | // Did we find anything?
59 | if (!image)
60 | {
61 | // Create image ID
62 | std::ostringstream id;
63 | id << "image" << (images.size() + 1);
64 |
65 | // Create a new image
66 | image = new Image(id.str(), path);
67 |
68 | // Add to document
69 | images.push_back(image);
70 | }
71 |
72 | // Return result
73 | return image;
74 | }
75 |
76 | // Find an image, returns NULL if not found
77 | Image* ImageCollection::Find(const std::string& path)
78 | {
79 | Image* result = nullptr;
80 |
81 | // Loop through images
82 | for (unsigned int i = 0; i < images.size(); i++)
83 | {
84 | // Do the paths match?
85 | if (images[i]->path == path)
86 | {
87 | // Found a match
88 | result = images[i];
89 | break;
90 | }
91 | }
92 |
93 | // Return result
94 | return result;
95 | }
96 |
97 | void ImageCollection::DebugInfo()
98 | {
99 | // Image debug info
100 | outFile << "\nBitmap images: " << images.size() << "
";
101 |
102 | // Anything to list?
103 | if (images.size() > 0)
104 | {
105 | // Start unordered list
106 | outFile << "\n";
107 |
108 | // Loop through each image
109 | for (unsigned int i = 0; i < images.size(); i++)
110 | {
111 | outFile << "\n - ID: " << images[i]->id <<
112 | ", path: Uri() << "\" target=\"_blank\">" << images[i]->path << "
";
113 | }
114 |
115 | // End unordered list
116 | outFile << "\n
";
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Source/ImageCollection.h:
--------------------------------------------------------------------------------
1 | // ImageCollection.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef IMAGECOLLECTION_H
24 | #define IMAGECOLLECTION_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Image.h"
28 | #include "Utility.h"
29 |
30 | namespace CanvasExport
31 | {
32 | // Globals
33 | extern ofstream outFile;
34 | extern bool debug;
35 |
36 | /// Represents a collection of images
37 | class ImageCollection
38 | {
39 | private:
40 |
41 | std::vector images; // Collection of image pointers
42 |
43 | public:
44 |
45 | ImageCollection();
46 | ~ImageCollection();
47 |
48 | void Render();
49 | Image* Add(const std::string& path);
50 | Image* Find(const std::string& path);
51 | void DebugInfo();
52 |
53 | };
54 | }
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/Source/Layer.cpp:
--------------------------------------------------------------------------------
1 | // Layer.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "Ai2CanvasSuites.h"
25 | #include "Layer.h"
26 |
27 | using namespace CanvasExport;
28 |
29 | Layer::Layer()
30 | {
31 | // Initialize Layer
32 | this->name = "";
33 | this->layerHandle = nullptr;
34 | this->artHandle = nullptr;
35 | this->hasGradients = false;
36 | this->hasPatterns = false;
37 | this->hasAlpha = false;
38 | this->crop = false;
39 |
40 | // Initialize bounds
41 | // Start with absolute maximums and minimums (these will be "trimmed")
42 | this->bounds.left = FLT_MAX;
43 | this->bounds.right = -FLT_MAX;
44 | this->bounds.top = -FLT_MAX;
45 | this->bounds.bottom = FLT_MAX;
46 | }
47 |
48 | Layer::~Layer()
49 | {
50 | }
51 |
52 | // ******************** GLOBAL FUNCTIONS ********************
53 |
54 | // Add a new layer
55 | Layer* CanvasExport::AddLayer(std::vector& layers, const AILayerHandle& layerHandle)
56 | {
57 | // Get layer name
58 | ai::UnicodeString layerName;
59 | sAILayer->GetLayerTitle(layerHandle, layerName);
60 | if (debug)
61 | {
62 | outFile << "\n// Layer name = " << layerName.as_Platform();
63 | }
64 |
65 | // Create a new layer
66 | Layer* layer = new Layer();
67 |
68 | // Set values
69 | layer->layerHandle = layerHandle;
70 | layer->name = layerName.as_Platform();
71 |
72 | // Add to document
73 | layers.push_back(layer);
74 |
75 | // Return result
76 | return layer;
77 | }
78 |
--------------------------------------------------------------------------------
/Source/Layer.h:
--------------------------------------------------------------------------------
1 | // Layer.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef LAYER_H
24 | #define LAYER_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Utility.h"
28 |
29 | namespace CanvasExport
30 | {
31 | // Globals
32 | extern ofstream outFile;
33 | extern bool debug;
34 |
35 | /// Represents a layer
36 | class Layer
37 | {
38 | private:
39 |
40 | public:
41 |
42 | Layer();
43 | ~Layer();
44 |
45 | std::string name; // Name of this layer
46 | AILayerHandle layerHandle; // Illustrator layer handle
47 | AIArtHandle artHandle; // First art in this layer
48 | AIRealRect bounds; // Bounds of the visible elements in this layer
49 | bool hasGradients; // Does this layer use gradients?
50 | bool hasPatterns; // Does this layer use pattern fills?
51 | bool hasAlpha; // Does this layer use alpha?
52 | bool crop; // Crop canvas to the bounds of this layer?
53 | };
54 |
55 | // Global functions
56 | Layer* AddLayer(std::vector& layers, const AILayerHandle& layerHandle);
57 | }
58 | #endif
59 |
--------------------------------------------------------------------------------
/Source/Pattern.cpp:
--------------------------------------------------------------------------------
1 | // Pattern.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "Pattern.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | // Unsure why Xcode requires the explicit namespace before the constructor
29 | CanvasExport::Pattern::Pattern()
30 | {
31 | // Initialize Pattern
32 | this->name = "";
33 | this->patternHandle = nullptr;
34 | this->canvasIndex = -1;
35 | this->isSymbol = false;
36 | this->hasGradients = false;
37 | this->hasPatterns = false;
38 | this->hasAlpha = false;
39 | }
40 |
41 | // Unsure why Xcode requires the explicit namespace before the destructor
42 | CanvasExport::Pattern::~Pattern()
43 | {
44 | }
45 |
--------------------------------------------------------------------------------
/Source/Pattern.h:
--------------------------------------------------------------------------------
1 | // Pattern.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef PATTERN_H
24 | #define PATTERN_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Utility.h"
28 |
29 | namespace CanvasExport
30 | {
31 | // Globals
32 | extern ofstream outFile;
33 | extern bool debug;
34 |
35 | /// Represents a pattern
36 | class Pattern
37 | {
38 | private:
39 |
40 | public:
41 |
42 | Pattern();
43 | ~Pattern();
44 |
45 | std::string name; // Name of the pattern/symbol
46 | AIPatternHandle patternHandle; // Handle to the pattern (for matching with artwork)
47 | int canvasIndex; // Index number for canvas
48 | bool isSymbol; // Is this pattern an Illustrator symbol?
49 | bool hasGradients; // Does this pattern use gradients?
50 | bool hasPatterns; // Does this pattern use pattern fills?
51 | bool hasAlpha; // Does this pattern use alpha?
52 |
53 | };
54 | }
55 | #endif
56 |
--------------------------------------------------------------------------------
/Source/PatternCollection.cpp:
--------------------------------------------------------------------------------
1 | // PatternCollection.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "PatternCollection.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | PatternCollection::PatternCollection()
29 | {
30 | // Initialize PatternCollection
31 | this->hasPatterns = false;
32 | this->hasSymbols = false;
33 | this->canvasIndex = 0;
34 | }
35 |
36 | PatternCollection::~PatternCollection()
37 | {
38 | // Clear patterns
39 | for (unsigned int i = 0; i < patterns.size(); i++)
40 | {
41 | // Remove instance
42 | delete patterns[i];
43 | }
44 | }
45 |
46 | std::vector& PatternCollection::Patterns()
47 | {
48 | return patterns;
49 | }
50 |
51 | bool PatternCollection::HasPatterns()
52 | {
53 | return hasPatterns;
54 | }
55 |
56 | bool PatternCollection::HasSymbols()
57 | {
58 | return hasSymbols;
59 | }
60 |
61 | // TODO: Should only add a new pattern if there is no existing pattern
62 | // Returns true if a new pattern was added, or false if it already exists
63 | bool PatternCollection::Add(AIPatternHandle patternHandle, bool isSymbol)
64 | {
65 | // Track whether or not this pattern exists
66 | bool patternExists = (Find(patternHandle) != nullptr);
67 |
68 | // Does it already exist?
69 | if (!patternExists)
70 | {
71 | // Create a new pattern
72 | Pattern* pattern = new Pattern();
73 |
74 | // Initialize default pattern values
75 | pattern->patternHandle = patternHandle;
76 | pattern->isSymbol = isSymbol;
77 |
78 | // If this is a pattern, track canvas index
79 | if (!isSymbol)
80 | {
81 | canvasIndex++;
82 | pattern->canvasIndex = canvasIndex;
83 | }
84 |
85 | // Get pattern name
86 | // TODO: Do we need to make this unique? Does Illustrator allow duplicates?
87 | ai::UnicodeString patternName;
88 | sAIPattern->GetPatternName(pattern->patternHandle, patternName);
89 | std::string name = patternName.as_Platform();
90 | CleanString(name, true);
91 | pattern->name = name;
92 |
93 | // Add to vector
94 | patterns.push_back(pattern);
95 |
96 | // Track this collection
97 | this->hasPatterns |= (!isSymbol);
98 | this->hasSymbols |= isSymbol;
99 | }
100 |
101 | return !patternExists;
102 | }
103 |
104 | // Find a pattern, returns NULL if not found
105 | CanvasExport::Pattern* PatternCollection::Find(AIPatternHandle patternHandle)
106 | {
107 | Pattern* result = nullptr;
108 |
109 | // Loop through patterns
110 | for (unsigned int i = 0; i < patterns.size(); i++)
111 | {
112 | // Do the handles match?
113 | if (patterns[i]->patternHandle == patternHandle)
114 | {
115 | // Found a match
116 | result = patterns[i];
117 | break;
118 | }
119 | }
120 |
121 | // Return result
122 | return result;
123 | }
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/Source/PatternCollection.h:
--------------------------------------------------------------------------------
1 | // PatternCollection.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef PATTERNCOLLECTION_H
24 | #define PATTERNCOLLECTION_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Ai2CanvasSuites.h"
28 | #include "Pattern.h"
29 | #include "Utility.h"
30 |
31 | namespace CanvasExport
32 | {
33 | // Globals
34 | extern ofstream outFile;
35 | extern bool debug;
36 |
37 | /// Represents a collection of patterns (which includes symbols)
38 | class PatternCollection
39 | {
40 | private:
41 |
42 | std::vector patterns; // Collection of patterns
43 | bool hasPatterns; // Does the collection include at least one pattern?
44 | bool hasSymbols; // Does the collection include at least one symbol?
45 | unsigned int canvasIndex; // Track next available canvas index
46 |
47 | public:
48 |
49 | PatternCollection();
50 | ~PatternCollection();
51 |
52 | bool Add(AIPatternHandle patternHandle, bool isSymbol);
53 | Pattern* Find(AIPatternHandle patternHandle);
54 | std::vector& Patterns();
55 | bool HasPatterns();
56 | bool HasSymbols();
57 | };
58 | }
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/Source/State.cpp:
--------------------------------------------------------------------------------
1 | // State.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "State.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | State::State()
29 | {
30 | // Default color string
31 | const std::string defaultColor("\"rgb(0, 0, 0)\"");
32 |
33 | // Initialize State
34 | // NOTE: These are the HTML5 canvas defaults: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#2dcontext
35 | this->globalAlpha = 1.0f;
36 | this->fillStyle = defaultColor;
37 | this->strokeStyle = defaultColor;
38 | this->lineWidth = 1.0f;
39 | this->lineCap = kAIButtCap;
40 | this->lineJoin = kAIMiterJoin;
41 | this->miterLimit = 10.0f;
42 | this->fontSize = 10.0f;
43 | this->fontName = "sans-serif";
44 | this->fontStyleName = "Regular";
45 | this->isProcessingSymbol = false;
46 | sAIRealMath->AIRealMatrixSetIdentity(&this->internalTransform);
47 | }
48 |
49 | State::~State()
50 | {
51 | }
52 |
53 | // Report state information
54 | void State::DebugInfo()
55 | {
56 | outFile << "\n\n// State Info";
57 | outFile << "\n// globalAlpha = " << setiosflags(ios::fixed) << setprecision(2) << this->globalAlpha;
58 | outFile << "\n// fillStyle = " << this->fillStyle;
59 | outFile << "\n// strokeStyle = " << this->strokeStyle;
60 | outFile << "\n// lineWidth = " << setiosflags(ios::fixed) << setprecision(1) << this->lineWidth;
61 | outFile << "\n// lineCap = " << this->lineCap;
62 | outFile << "\n// lineJoin = " << this->lineJoin;
63 | outFile << "\n// miterLimit = " << setiosflags(ios::fixed) << setprecision(1) << this->miterLimit;
64 | outFile << "\n// fontSize = " << setiosflags(ios::fixed) << setprecision(1) << this->fontSize;
65 | outFile << "\n// fontName = " << this->fontName;
66 | outFile << "\n// fontStyleName = " << this->fontStyleName;
67 | outFile << "\n// isProcessingSymbol = " << this->isProcessingSymbol;
68 | outFile << "\n// internalTransform = ";
69 | //RenderTransform(state.internalTransform);
70 | }
71 |
--------------------------------------------------------------------------------
/Source/State.h:
--------------------------------------------------------------------------------
1 | // State.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef STATE_H
24 | #define STATE_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Utility.h"
28 |
29 | namespace CanvasExport
30 | {
31 | // Globals
32 | extern ofstream outFile;
33 | extern bool debug;
34 |
35 | /// Represents a context drawing state
36 | class State
37 | {
38 | private:
39 |
40 | public:
41 |
42 | State();
43 | ~State();
44 |
45 | AIReal globalAlpha; // Global canvas alpha value (0.0 - 1.0)
46 | std::string fillStyle; // String fill style (e.g. "rgb(0, 0, 0)")
47 | std::string strokeStyle; // String stroke style (e.g. "rgb(0, 0, 0)")
48 | AIReal lineWidth; // Stroke width (in pixels)
49 | AILineCap lineCap; // Cap type
50 | AILineJoin lineJoin; // Join type
51 | AIReal miterLimit; // Stroke miter limit
52 | AIReal fontSize; // Font size (in pixels)
53 | std::string fontName; // Font name
54 | std::string fontStyleName; // Style name
55 | AIBoolean isProcessingSymbol; // Is an Illustrator symbol being processed?
56 | AIRealMatrix internalTransform; // Internal transformation for adjustments from Illustrator to canvas coordinate space
57 |
58 | void DebugInfo();
59 | };
60 |
61 | }
62 | #endif
63 |
--------------------------------------------------------------------------------
/Source/Trigger.cpp:
--------------------------------------------------------------------------------
1 | // Trigger.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "Trigger.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | Trigger::Trigger()
29 | {
30 | // Initialize Trigger
31 | this->parsedOkay = false;
32 | this->sourceObject = "";
33 | this->sourceClock = "";
34 | this->sourceEvent = "";
35 | this->triggeredFunction = "";
36 | }
37 |
38 | Trigger::~Trigger()
39 | {
40 | }
41 |
42 | void Trigger::SetParameter(const std::string& parameter, const std::string& value)
43 | {
44 | std::string parameterName = parameter;
45 |
46 | // Need to modify any "short-cuts"?
47 | if (parameterName == "fast-forward")
48 | {
49 | // Change to correct JavaScript function name
50 | parameterName = "fastForward";
51 | }
52 |
53 | // Parameter should be the name of the trigger
54 | this->triggeredFunction = parameterName;
55 |
56 | // Parse value into object-clock-event
57 | // Store as strings for now, since they'll have to be bound after everything has been parsed
58 |
59 | // Tokenize the values
60 | std::vector values = Tokenize(value, "-");
61 |
62 | // Process based on whether we have 2 or 3 values
63 | switch (values.size())
64 | {
65 | case 2:
66 | {
67 | // Is this a valid event?
68 | if (IsValidEvent(values[1]))
69 | {
70 | // object-event (object has a single clock...like an animation path function)
71 | this->sourceObject = values[0];
72 | this->sourceClock = "";
73 | this->sourceEvent = values[1];
74 |
75 | // Note that we parsed
76 | this->parsedOkay = true;
77 | }
78 |
79 | break;
80 | }
81 | case 3:
82 | {
83 | // Is this a valid event?
84 | if (IsValidEvent(values[2]))
85 | {
86 | // object-clock-event (object has multiple clocks...like a draw function)
87 | this->sourceObject = values[0];
88 | this->sourceClock = values[1];
89 | this->sourceEvent = values[2];
90 |
91 | // Note that we parsed
92 | this->parsedOkay = true;
93 | }
94 |
95 | break;
96 | }
97 | }
98 |
99 | if (debug)
100 | {
101 | outFile << "\n// triggeredFunction = " << this->triggeredFunction;
102 | outFile << "\n// sourceObject = " << this->sourceObject;
103 | outFile << "\n// sourceClock = " << this->sourceClock;
104 | outFile << "\n// sourceEvent = " << this->sourceEvent;
105 | }
106 | }
107 |
108 | // Is the value a valid event name?
109 | bool Trigger::IsValidEvent(const std::string& value)
110 | {
111 | return (value == "started" ||
112 | value == "stopped" ||
113 | value == "iterated" ||
114 | value == "finished");
115 | }
116 |
117 | void Trigger::JSTriggerInit(const std::string& objectName, const std::string& clockName)
118 | {
119 | if (this->parsedOkay)
120 | {
121 | // Output JavaScript initialization
122 | // animations[0].pathClock.finished.subscribe(function() { animations[0].pathClock.reset(); });
123 | outFile << "\n " << this->sourceObject <<
124 | "." << this->sourceClock <<
125 | "." << this->sourceEvent << ".subscribe(function() { " <<
126 | objectName << "." <<
127 | clockName << "." <<
128 | this->triggeredFunction << "(); });";
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/Source/Trigger.h:
--------------------------------------------------------------------------------
1 | // Trigger.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef TRIGGER_H
24 | #define TRIGGER_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Utility.h"
28 |
29 | namespace CanvasExport
30 | {
31 | // Globals
32 | extern ofstream outFile;
33 | extern bool debug;
34 |
35 | // Represents an animation trigger
36 | class Trigger
37 | {
38 | private:
39 |
40 | public:
41 |
42 | Trigger();
43 | ~Trigger();
44 |
45 | bool parsedOkay; // Did the parse complete okay?
46 | std::string sourceObject; // Name of the source object
47 | std::string sourceClock; // Name of the source animation clock
48 | std::string sourceEvent; // Name of the source event
49 | std::string triggeredFunction; // Name of the triggered function
50 |
51 | void SetParameter(const std::string& parameter, const std::string& value);
52 | bool IsValidEvent(const std::string& value);
53 | void JSTriggerInit(const std::string& objectName, const std::string& clockName);
54 | };
55 | }
56 | #endif
57 |
--------------------------------------------------------------------------------
/Source/Utility.cpp:
--------------------------------------------------------------------------------
1 | // Utility.cpp
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #include "IllustratorSDK.h"
24 | #include "Utility.h"
25 |
26 | using namespace CanvasExport;
27 |
28 | // TODO: Consider something more like: fprintf(m_fp, "\n%*sIndented by 2", 2, "");
29 | // Or std::string(indent, ' ')
30 | std::string CanvasExport::Indent(size_t depth)
31 | {
32 | if (debug)
33 | {
34 | return std::string((depth * 2), ' ');
35 | }
36 | else
37 | {
38 | return " ";
39 | }
40 | }
41 |
42 | bool CanvasExport::OpenFile(const std::string& filePath)
43 | {
44 | // Open the file
45 | outFile.open(filePath.c_str(), ios::out);
46 |
47 | // Return result
48 | return outFile.is_open();
49 | }
50 |
51 | void CanvasExport::CloseFile()
52 | {
53 | // Close the file
54 | outFile.close();
55 | }
56 |
57 | void CanvasExport::RenderTransform(const AIRealMatrix& matrix)
58 | {
59 | // Transform
60 | outFile << setiosflags(ios::fixed) << setprecision(3) <<
61 | matrix.a << ", " << matrix.b << ", " << matrix.c << ", " << matrix.d << ", " <<
62 | setprecision(1) <<
63 | matrix.tx << ", " << matrix.ty;
64 | }
65 |
66 | // In-place replacement of one character for another
67 | void CanvasExport::Replace(std::string& s, char find, char replace)
68 | {
69 | // Loop through string
70 | for (unsigned int i = 0; i < s.length(); i++)
71 | {
72 | // Does this character match?
73 | if (s[i] == find)
74 | {
75 | // Replace the character
76 | s[i] = replace;
77 | }
78 | }
79 | }
80 |
81 | // Removes spaces and other invalid characters from the string
82 | // camelCase == true, converts string to camel case
83 | // TODO: Should we allow dashes and periods here? Or use a separate function to clean those?
84 | void CanvasExport::CleanString(std::string& s, AIBoolean camelCase)
85 | {
86 | int destIndex = 0;
87 | AIBoolean newWord = true; // Are we processing a new word?
88 | AIBoolean firstLetter = true; // Are we looking for the first letter (so we can make lower-case)?
89 |
90 | // Loop through the whole string
91 | for (unsigned int i = 0; i < s.length(); i++)
92 | {
93 | // Is this a valid character?
94 | if ((s[i] >= '0' && s[i] <= '9') ||
95 | (s[i] >= 'A' && s[i] <= 'Z') ||
96 | (s[i] >= 'a' && s[i] <= 'z') ||
97 | (s[i] == ' '))
98 | {
99 | // If we're doing camel casing
100 | if (camelCase)
101 | {
102 | // Do we need to watch for a new word?
103 | if (s[i] == ' ')
104 | {
105 | // Watching for new word
106 | newWord = true;
107 | }
108 | else
109 | {
110 | // Are we watching for a new word?
111 | if (newWord)
112 | {
113 | // Have we processed the first letter yet?
114 | if (firstLetter)
115 | {
116 | // Is the first letter upper-case?
117 | if (s[i] >= 'A' && s[i] <= 'Z')
118 | {
119 | // Make lower-case
120 | s[i] += 32;
121 | }
122 |
123 | // No longer watching for the first letter
124 | firstLetter = false;
125 | }
126 | else
127 | {
128 | // Do we have a lower-case letter we need to make upper-case?
129 | if (s[i] >= 'a' && s[i] <= 'z')
130 | {
131 | // Make upper-case
132 | s[i] -= 32;
133 | }
134 | }
135 |
136 | // No longer watching for a new word
137 | newWord = false;
138 | }
139 | }
140 | }
141 |
142 | // If we don't have a space or we're not doing camel casing
143 | if (s[i] != ' ' || !camelCase)
144 | {
145 | // Copy the character
146 | s[destIndex] = s[i];
147 |
148 | // Move destination index to next character
149 | destIndex++;
150 | }
151 | }
152 | }
153 |
154 | // Remove any remaining characters
155 | s.erase(destIndex);
156 | }
157 |
158 | // If they exist, removes parenthesis and parameters from a function name
159 | void CanvasExport::CleanFunction(std::string& s)
160 | {
161 | size_t length = s.length();
162 | if (length > 3)
163 | {
164 | // Does the end of the string contain function syntax?
165 | if (s.substr(length - 2) == ");")
166 | {
167 | // Find the opening parenthesis
168 | size_t index = s.find_last_of('(');
169 |
170 | // Did we find the parenthesis?
171 | if (index != string::npos)
172 | {
173 | // Terminate the name starting at the opening parenthesis
174 | s.erase(index);
175 | }
176 | }
177 | }
178 | }
179 |
180 | // Cleans a function parameter value
181 | void CanvasExport::CleanParameter(std::string& s)
182 | {
183 | int destIndex = 0;
184 |
185 | // Loop through the whole string
186 | for (unsigned int i = 0; i < s.length(); i++)
187 | {
188 | // Is this a valid character?
189 | if ((s[i] >= '0' && s[i] <= '9') ||
190 | (s[i] >= 'A' && s[i] <= 'Z') ||
191 | (s[i] >= 'a' && s[i] <= 'z') ||
192 | (s[i] == '-') ||
193 | (s[i] == '.') ||
194 | (s[i] == ','))
195 | {
196 | // Copy the character
197 | s[destIndex] = s[i];
198 |
199 | // Move destination index to next character
200 | destIndex++;
201 | }
202 | }
203 |
204 | // Remove any remaining characters
205 | s.erase(destIndex);
206 | }
207 |
208 | // Turn a string into a valid HTML ID
209 | // HTML5 ID draft spec: http://dev.w3.org/html5/spec/elements.html#the-id-attribute
210 | // Note that most references recommend using A-Z, a-z, 0-9, and should begin with an alpha character
211 | // Technically, hyphens ("-"), underscores ("_"), colons (":"), and periods (".") are allowed, but they're known to cause issues with things like jQuery
212 | void CanvasExport::MakeValidID(std::string& s)
213 | {
214 | // First, clean the string so that it only contains camel-cased alpha-numeric data
215 | CleanString(s, true);
216 |
217 | // Check to see if the first character is numeric
218 | if (s[0] >= '0' && s[0] <= '9')
219 | {
220 | // String starts with a number, so arbitrarily prepend an 'a'
221 | s.insert(0, "a");
222 | }
223 | }
224 |
225 | void CanvasExport::ToLower(std::string& s)
226 | {
227 | // Loop through the whole string
228 | for (unsigned int i = 0; i < s.length(); i++)
229 | {
230 | // Is the letter upper-case?
231 | if (s[i] >= 'A' && s[i] <= 'Z')
232 | {
233 | // Make lower-case
234 | s[i] += 32;
235 | }
236 | }
237 | }
238 |
239 | // Handy tokenize function
240 | vector CanvasExport::Tokenize(const std::string& str, const std::string& delimiters)
241 | {
242 | std::vector tokens;
243 |
244 | // skip delimiters at beginning.
245 | std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
246 |
247 | // find first "non-delimiter".
248 | std::string::size_type pos = str.find_first_of(delimiters, lastPos);
249 |
250 | while (std::string::npos != pos || std::string::npos != lastPos)
251 | {
252 | // found a token, add it to the vector.
253 | tokens.push_back(str.substr(lastPos, pos - lastPos));
254 |
255 | // skip delimiters. Note the "not_of"
256 | lastPos = str.find_first_not_of(delimiters, pos);
257 |
258 | // find next "non-delimiter"
259 | pos = str.find_first_of(delimiters, lastPos);
260 | }
261 |
262 | return tokens;
263 | }
264 |
265 | bool CanvasExport::FileExists(const std::string& fileName)
266 | {
267 | ai::UnicodeString aiFileName(fileName);
268 | ai::FilePath filePath(aiFileName);
269 |
270 | return filePath.Exists(true);
271 | }
272 |
273 | // Update bounds to include newBounds
274 | // TODO: Is there an Illustrator function to do this?
275 | void CanvasExport::UpdateBounds(const AIRealRect& newBounds, AIRealRect& bounds)
276 | {
277 | // Update minimums and maximums
278 | if (newBounds.top > bounds.top)
279 | {
280 | bounds.top = newBounds.top;
281 | }
282 | if (newBounds.left < bounds.left)
283 | {
284 | bounds.left = newBounds.left;
285 | }
286 | if (newBounds.bottom < bounds.bottom)
287 | {
288 | bounds.bottom = newBounds.bottom;
289 | }
290 | if (newBounds.right > bounds.right)
291 | {
292 | bounds.right = newBounds.right;
293 | }
294 | }
295 |
296 | // Find a unique filename
297 | // Path should have a trailing backslash ("c:\output\"), and extension should include a period (".png")
298 | std::string CanvasExport::GetUniqueFileName(const std::string& path, const std::string& fileName, const std::string& extension)
299 | {
300 | // Find a unique filename
301 | std::ostringstream uniqueFileName;
302 |
303 | // Find a unique file name
304 | int unique = 0;
305 | do
306 | {
307 | // Increment to make unique name
308 | unique++;
309 |
310 | // Generate a unique file name
311 | uniqueFileName.str("");
312 | uniqueFileName << fileName << unique << extension;
313 | } while (FileExists((path + uniqueFileName.str())));
314 |
315 | // Return unique file name
316 | return uniqueFileName.str();
317 | }
318 |
319 | void CanvasExport::WriteArtTree()
320 | {
321 | AILayerHandle layerHandle = nullptr;
322 | ai::int32 layerCount = 0;
323 |
324 | // How many layers in this document?
325 | sAILayer->CountLayers(&layerCount);
326 |
327 | // Loop through all layers
328 | for (ai::int32 i = 0; i < layerCount; i++)
329 | {
330 | // Get a reference to the layer
331 | sAILayer->GetNthLayer(i, &layerHandle);
332 |
333 | // Get the first art in this layer
334 | AIArtHandle artHandle = nullptr;
335 | sAIArt->GetFirstArtOfLayer(layerHandle, &artHandle);
336 |
337 | // Dig in
338 | WriteArtTree(artHandle, 0);
339 | }
340 | }
341 |
342 | void CanvasExport::WriteArtTree(AIArtHandle artHandle, int depth)
343 | {
344 | // Simple way to describe art types for debugging purposes
345 | static const char *artTypes[] =
346 | {
347 | "kUnknownArt", "kGroupArt", "kPathArt", "kCompoundPathArt", "kTextArtUnsupported", "kTextPathArtUnsupported", "kTextRunArtUnsupported", "kPlacedArt", "kMysteryPathArt", "kRasterArt", "kPluginArt", "kMeshArt", "kTextFrameArt", "kSymbolArt", "kForeignArt", "kLegacyTextArt"
348 | };
349 |
350 | // Loop through art and its siblings
351 | do
352 | {
353 | // Art type
354 | short type = 0;
355 | sAIArt->GetArtType(artHandle, &type);
356 | outFile << "\n//" << Indent(depth) << std::string(artTypes[type]) << " (" << type << ")";
357 |
358 | // Get art name
359 | ai::UnicodeString artName;
360 | AIBoolean isDefaultName = false;
361 | sAIArt->GetArtName(artHandle, artName, &isDefaultName);
362 | outFile << ": " << artName.as_Platform();
363 |
364 | // Any children?
365 | AIArtHandle childArtHandle;
366 | sAIArt->GetArtFirstChild(artHandle, &childArtHandle);
367 | if (childArtHandle != nullptr)
368 | {
369 | WriteArtTree(childArtHandle, depth + 1);
370 | }
371 |
372 | // Find the next sibling
373 | sAIArt->GetArtSibling(artHandle, &artHandle);
374 | }
375 | while (artHandle != nullptr);
376 | }
377 |
--------------------------------------------------------------------------------
/Source/Utility.h:
--------------------------------------------------------------------------------
1 | // Utility.h
2 | //
3 | // Copyright (c) 2010-2022 Mike Swanson (http://blog.mikeswanson.com)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #ifndef UTILITY_H
24 | #define UTILITY_H
25 |
26 | #include "IllustratorSDK.h"
27 | #include "Ai2CanvasSuites.h"
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | namespace CanvasExport
34 | {
35 | // Globals
36 | extern ofstream outFile;
37 | extern bool debug;
38 |
39 | bool OpenFile(const std::string& filePath);
40 | void CloseFile();
41 | std::string Indent(size_t depth);
42 | void RenderTransform(const AIRealMatrix& matrix);
43 | void Replace(std::string& s, char find, char replace);
44 | void CleanString(std::string& s, AIBoolean camelCase);
45 | void CleanFunction(std::string& s);
46 | void CleanParameter(std::string& s);
47 | void ToLower(std::string& s);
48 | void MakeValidID(std::string& s);
49 | vector Tokenize(const std::string& str, const std::string& delimiters);
50 | bool FileExists(const std::string& fileName);
51 | void UpdateBounds(const AIRealRect& newBounds, AIRealRect& bounds);
52 | std::string GetUniqueFileName(const std::string& path, const std::string& fileName, const std::string& extension);
53 | void WriteArtTree();
54 | void WriteArtTree(AIArtHandle artHandle, int depth);
55 | }
56 | #endif
57 |
--------------------------------------------------------------------------------
/plugin.pipl:
--------------------------------------------------------------------------------
1 | ADBEkind SPEAADBEivrs ADBEmi32 ADBEpinm Ai2Canvas
--------------------------------------------------------------------------------