• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Cross-document Swatch Color Update Troubles (C++)

Community Beginner ,
Oct 14, 2017 Oct 14, 2017

Copy link to clipboard

Copied

Hello there,

I am using Visual Studio 2015 with Adobe Illustrator CC 2017 with the latest version Adobe Illustrator SDK.

As I am completely new to working with the Adobe SDK I've spent some time over the past weeks becoming more familiar with the documentation, and have learned through gradually building the parts of this solution which I am able. What I have come up with is a single menu item under 'window' which toggles the collection of swatch data from the active document. With this data collected, opening a subsequent document results in a notifier that triggers the update code, so the destination's swatch colors are to be updated. So far so good.

My task is to develop a plug in which is able to read the color swatches from a source Illustrator document and apply them to a large number of destination Illustrator documents one at a time. For the moment, I am focusing on updating just one swatch in one document. All swatches in these documents share a naming convention, so at first glance it seems a matter of copying the color from the source swatch to the destination.

Initially this had been attempted with ActionScript, but became clear that language lacks access credentials (presumably) required to retrieve color data from swatches; the source document's color swatches' color data cannot be read (or returns empty data). Now in C++, it seems the data can be read and it's been possible to update one swatch - at least to the point that the color changes, but only in the swatches window (the areas of the document with that color do not update), only when I also include program code to change the swatch name though the name never visibly changes, and only when I hard-code the color values to be set in the destination swatch. Still, that's something.

In a prior attempt, I was using the following code for this task. Doing so results in the 'updated' swatches in the destination document disappearing (without the document's colors being affected). Also, in the source document, the swatch names of corresponding swatches update to become 'Deleted Global Color x" (x ranging from "" to 18). When exiting Adobe Illustrator subsequently, Illustrator crashes.

I am including this portion because it illustrates some of the steps I have gone to in attempts to resolve this matter. The program code I am actually curious about occurs later in this post.

Illustrator observed behavior:

- changes any swatch name accessed in the source document's swatch window to 'Deleted color Number x"

(The test destination document has 22 swatches and 18 are to be updated).

- deletes any updated swatch from the destination document's swatches window, thus four remain.

- crashes on program exit.

count = sAISwatches->CountSwatches(fMasterSwatchList);

for (int i = 0; i < count; i++)

{

     masterSwatch = sAISwatches->GetNthSwatch(fMasterSwatchList, i);

     result = sAISwatches->GetSwatchName(masterSwatch, swatchName);

     sAISwatches->GetSwatchName(masterSwatch, swatchName);

     // skip certain swatches

     if (swatchName != ai::UnicodeString("[None]") &&

         swatchName != ai::UnicodeString("[Registration]") &&

         swatchName != ai::UnicodeString("White") &&

         swatchName != ai::UnicodeString("Black"))

     {

          slaveSwatch = sAISwatches->GetSwatchByName(NULL, swatchName);

          if (slaveSwatch != NULL)

          {

               result = sAISwatches->GetAIColor(masterSwatch, &swatchColor);

               if (result) return result;

               result = sAISwatches->SetAIColor(slaveSwatch, &swatchColor);

               if (result) return result;

          }

     }

}

In order for any modicum of success to occur I have had to make use of some example code I found in the Adobe Illustrator forums from 2007. I have found with that code, it is possible to update one of the swatches in a destination document, but only when I include code for the name of that swatch to be changed (though the name doesn't actually update in the swatches window). The swatch so-updated becomes dissociated from the document such that manually adjusting its color value in Illustrator with the preview box checked has no visible effect on the so-colored swatches in the document view. It seems a clue as to why only the swatch window's view of the color is updating, but we need the colors to update in the document view as well.

I have included the relevant program code below, and hopefully it is enough to highlight what is happening herein. I would be so very grateful if somebody with a little more expertise on these matters could lend a hand. Thanking you in advance.

Also, by the point at which this code runs, the swatches from the master document have been obtained. The code is run upon receipt of the document opened notification.

/* example code */

// select relevant color profile.

AIColorProfile rgb, cmyk, gray;

result = sAIDocument->GetDocumentProfiles(&rgb, &cmyk, &gray);

ai::UnicodeString name;

if (rgb)

     result = sAIOverrideColorConversion->GetProfileName(rgb, name);

else if (cmyk)

     result = sAIOverrideColorConversion->GetProfileName(cmyk, name);

else

     result = sAIOverrideColorConversion->GetProfileName(gray, name);

string s = name.as_Roman();

short colorModel;

result = sAIDocument->GetDocumentColorModel(&colorModel);

// above code appears unrelated to the function's remainder

// attempt to find a color in the swatch palette

ai::UnicodeString colorName("WM_Blue");

AICustomColorHandle colorHandle;

AICustomColor color;

// find the color name in the doc's swatch

result = sCustomColor->GetCustomColorByName(colorName, &colorHandle);

if (result == 0)

{

     result = sCustomColor->GetCustomColor(colorHandle, &color);

     AIDocumentHandle document = NULL;

     result = sAIDocument->GetDocument(&document);

     AISwatchListRef swatchList;

     result = sAISwatches->GetSwatchList(document, &swatchList);

     AISwatchRef swatch = NULL;

     swatch = sAISwatches->GetSwatchByName(swatchList, colorName);

     if (swatch)

     {

          // it is only by changing the swatch name - which doesn't actually update

          // the name in the swatches window, that the color update becomes visible,

          // and then, it is not reflected in the document swatches, just in the

          // swatch window.

          result = sAISwatches->SetSwatchName(swatch, ai::UnicodeString("Test"));

          AIColor aiColor;

          color.c.rgb.red = 0.7685;

          color.c.rgb.green = 0.051;

          color.c.rgb.blue = 0.051;

          color.flag = kCustomRegistrationColor;

          color.kind = kCustomThreeColor;

          result = sCustomColor->NewCustomColor(&color, colorName, &colorHandle);

          aiColor.kind = kCustomColor;

          aiColor.c.c.tint = 0.0f;

          aiColor.c.c.color = colorHandle;

          result = sAISwatches->SetAIColor(swatch, &aiColor);

     }

}

TOPICS
SDK

Views

1.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , Oct 27, 2017 Oct 27, 2017

I haven't done much with swatches, but having experimented with some code, it seems that both spot colors and global process colors use custom color handles. These swatches reference the custom colors in the document. To achieve what you want, you don't actually have to do anything with the swatches, you just change the color values of the custom colors in the document:

        AICustomColorHandle colorHandle = NULL;

        sCustomColor->GetCustomColorByName(ai::UnicodeString("WM_Black"),&colorHa

...

Votes

Translate

Translate
Adobe
Advocate ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

"With this data collected, opening a subsequent document results in a notifier that triggers the update code,"

Is the update code called from an SDK message or some platform specific code (e.g. windows timer). If it is the latter, the problem is probably becuase the plugin context is not set properly (see AppContext class in samplecode/common/source)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

While the AppContext can be important, if he's responding to a notifier, it'll be set for him.

I have a lot of experience with what you're trying to do; I expect I have more than anyone outside of Adobe. Copying swatches & the like between document is, unfortunately, not really supported by the API. But it is doable.

If you were just copying RGB/CMYK values, you'd be fine. But if even one of those swatches has a pattern or gradient, you're headed for Crash City. Because those objects (patterns & gradients) have handles, and are saved locally in their document. When you perform a naive copy of a swatch that contains such an object, you create a swatch that has a pointer to a resource in another document. You can probably get a crash just by closing the source document and trying to do something with the copied swatch, as it attempts to render by following that pointer to random memory.

The answer is, unfortunately, tedious. You have to manually handle all of this. Basically, when you're evaluating a swatch for copying, you need to inspect its type and act accordingly. If it's a gradient, create a new gradient object in the destination document, and configure it using the settings from the source swatch's gradient. Then, create your new swatch in the destination document and point it's gradient handle at your newly created gradient.

Follow this pattern for *anything* that has a handle. This includes patterns (which I believe can be Retarget'd to a new document save you some grief). Note that even simple AIColor objects can have gradient handles (and custom colours also have handles). It's just a matter of covering all your bases.

If you run into a situation where you don't know how to handle a case, let me know and I'll look up how I did it. I'm pretty confident I've covered everything at this point, but it took us a while to get there (every so often a user would unearth a member-of-a-member that was a handle and I missed).

Good luck! Hope this helps!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

Hello,

Thank you for pointing all of these cases out. We are working with basic AIColor swatches at this point and from what I have gathered, that will continue to be the case. As you suspected, our code is being called by the DocumentOpenedNotifier, and from what you've said concerning the data pointers, I better understand what is causing the trouble, as well as the crashes - very interesting.

While I'm happy to figure it out on my own, the temptation to not reinvent the wheel here leaves me curious to see a working example of how you went about updating swatch colors (custom colors), such that the destination document's colors also updated.

Thanks again for the insight into this matter,

Jeremy.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

Our main concern was copying of artwork & large internal objects that referred often to swatches, graphics styles, character styles & symbols. As soon as we made the decision to let users move these objects between documents, my headaches in this area began

There's no one spot for all of this. We have a rich OO API that hides most of the AI API behind much nicer to use methods & objects. So we have our own CColour, CSwatch & CGradient objects (the former having various derivatives to cover custom colours, lab colours, etc.). Each of these know how to copy themselves between documents using the same method: CopyTo(), which supplies the destination document and the object I refer to as the 'scratchpad'.

A scratchpad is created for every inter-document operation, and serves as memory for the life of the operation. As we iterate over the art and copy it, we check if its style or swatch has been copied already; if not, it's copied there (calling CopyTo()) and a mapping is established between the old handle and the new for that object (e.g. swatch, symbol, style, etc.). The next time something using that object comes along, it determines it's already been copied and gets the new handle, and assigns that to the destination copy of the artwork.

It works similarly for our internal objects; they all have a CopyTo() and when they copy their internal members, they check the scratchpad.

Some things are done automatically by Illustrator, albeit badly. I forget which ones do it, but for some (symbols I think?) AI creates a new copy of the style/symbol for every art object that has it when it's copied. So one of the things the scratchpad does is it enumerates the pre-existing styles in the destination document. Then, when we're done, it deletes anything it finds that either was there to start, or is in our style/symbol/swatch mapping. This eliminates a lot of crud that used to be left on the other side.

All of this could be greatly simplified if Adobe exposed whatever they use -- and they must have something, since you can just cut & paste art between documents with none of these headaches! -- but that doesn't seem to be forthcoming

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

Please do forgive, as I am learning all of this on the fly. What I am seeing in the Swatches suites is there are no access points to adjust addresses of any referenced swatches. I understand that you have a custom OO API sitting beyond and interfacing with the Adobe API to conduct, for example, swatch updating between documents. The rest of your explanation is clear enough, but reading between the lines of your reply, and as I've had a brief glance at AIColor.h, I am curious if your API achieves copying of swatches through document model walking of the source and destination or if there is a slightly higher-level alternative. I've yet to investigate that as a possible solution, but would appreciate being pointed in the right direction in terms of where I need to look or what I need to look at, for ways to ensure swatch memory addresses will be properly managed during the update. As you surely know, the API documentation seems to make little reference to this, at least from what I've seen so-far.

Thanks again for your time and advice,

Jeremy.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 16, 2017 Oct 16, 2017

Copy link to clipboard

Copied

According to this document the way to copy swatches between documents as a user is to import a document as a swatch library:

How to use and create swatches in Illustrator

As Mr Patterson has said, the SDK seems to be lacking in this area, e.g. you can’t load a swatch library from a file.

When things are not available in the SDK, you sometimes have to resort to hacks which can get a bit messy. Playing around in Illustrator, I think you can achieve what you are trying to do by opening document A and document B which have different swatch colors. If you want the swatch colors in document A to be used in document B, you delete all the art from document A and then copy and paste the art from document B to document A, then save as document B. This assumes the documents are the same size, otherwise you will also have to resize the document. You should be able to do all of that from the SDK.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 17, 2017 Oct 17, 2017

Copy link to clipboard

Copied

The other problem with copying art from one document to another is that you lose all the layer information, so you would also have to rebuild that. If you were going to support all swatch types, this approach might be worth pursuing, but you say you are only going to be using simple colors, then your original approach is probably easier. The only handles you have to worry about are the custom color handles. You can create new handles in the new document and then copy over the color values from the old document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 17, 2017 Oct 17, 2017

Copy link to clipboard

Copied

Not sure what you mean, but what we do is very boring and straight forward.

When we encounter a swatch we want to move from document A to document B, we simply switch to document B and create a new swatch with all the information from the original swatch. If we're copying art at the same time, we copy the art across, then update the fill/stroke/whatever to point to our newly created swatch. That this is all done in in classes just makes each component its own thing. Copying a CSwatch will copy itself, and if it contains, for example, a gradient, it creates new a CGradient and lets that copy itself, etc. You don't have to do it this way of course -- if all of your code is for doing just this copying, might as well do it all in one place! -- but we have this problem all over our product because we have lots of examples of referring to swatches & styles in things like style sheets.

Hmmm, looking at some of our code in one spot, I wonder if I didn't over-complicate it. I notice there's a method in AIPathStyle.h called RetargetForCurrentDoc that takes an AIColor as a parameter. I suspect you might just be able to switch to the destination document and call that on the AIColor, and it may take care of gradients & everything else automatically. I'll have to try that myself and see if that reduces my code footprint. Ironically, I am using it already when copying a graphics style; I create a new style and iterate the style's paint fields, using that method on each.

AISymbol.h has one for handling symbols if that ever comes up, but I knew about that one -- I use it already. Incidentally, one of the nice little secret nuggets of the AI SDK is that you can pull styles from saved documents pretty easily -- as Leo alluded too -- using some functions in AIPathStyle.h. That only works on saved documents unfortunately, not open and unsaved documents (as is the situation I believe you're handling, as I am).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 25, 2017 Oct 25, 2017

Copy link to clipboard

Copied

Perhaps it wouldn't be such a problem to have the code pull the styles from a saved document, except that the end user doesn't want to have to recompile the code every time they change the name of the document that contains the master swatch palette for their projects. The document set which they will be updating is quite large so I am doing all I can to ensure the solution provided uses an efficient workflow. This is also why I don't feel there is a viable means of doing this manually in the way Leo has suggested.

A recent attempt to do so involved loading the document dictionary but iterating over that revealed only attributes that my code was adding to it (only the srgb key was listed, but the iterator also didn't exit properly for some reason). It felt like a dead end so I haven't pursued that avenue further at this time.

In my second code listing in the original post, inserting this at line 62 is what I believe you have suggested in your most recent reply:

result = sAIPathStyle->RetargetForCurrentDoc(&aiColor);

I found this code was only visibly effective if I placed it before any of the color copying (at line 30). At that point, it prompts me to merge or add this conflicting swatch to the new document. This is what happens when we have attempted this using manual action. The second option creates a new swatch and the first option "merges" the swatch but ultimately discards the source colors in lieu of the destination's so again, unless I'm missing something (and I surely am...), this seems to be ineffective as well. As with all things related to coding I do keep the tidbits around in case they prove useful or I realize how to make proper use of them later. That is to say, none of the suggestions made so-far are being outright discarded, but more-or-less filed away into a state of "I don't fully understand how to use this yet.".

Prior to today's attempts, I have been working with your suggestions since they were made, time permitting, and continued to experience no results, or rather, the results that the one test swatch color changes in the destination swatch palette but neither its name (which we wouldn't want to change anyway), or the document, visually or otherwise, are updated. Despite concerted efforts, to date I have yet to determine a means of revealing or working with any memory pointers within the source or destination documents. I've considered that you may be referring simply to the variables being used to store the colors temporarily so I attempted to write a deeper copy of an AIColor object all in one place, which used AIColor.kind to reveal the flags being used on a test color swatch, to trigger copying of the relevant member values between source and destination color.

In my case the flags are kPattern, kNoneColor, kCustomLabColor, kCustomColor, kThreeColor, kFourColor and kCustomThreeColor, so based on these flags I can copy each value from each attribute in the source AIColor.c (b.*, c.*, f.*, g.*, p.*, rgb.*) to each value of each attribute in the destination AIColor.c, as well as .kind. The flags kNoneColor, kCustomLabColor, and kCustomThreeColor do not have any data, nor accessors associated to copy, so I left those blocks blank for now.

Through the use of this method, I was able to see that the swatch color copies from the source to the destination, but again it is only in the swatch palette and still breaks the reference in the destination document.

With respect, it is all fine and well to say that program code is boring and straight forward when it has been written properly to accomplish its intended task.

You can see my code and yours. In terms of how to modify the color of a swatch such that it also updates in the document view / maintains its references so that the modified swatch can still be adjusted within the palette, what am I missing?

Thanking you in advance for your patience and assistance,

Jeremy.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 25, 2017 Oct 25, 2017

Copy link to clipboard

Copied

No worries Jeremy! I'm sorry it hasn't worked out so far. I didn't realize that RetargetForCurrentDoc() caused a UI element to pop up; I probably did at one point, but I wrote most of this years ago and have (happily) forgotten much of the details. That's probably why I'm not using it now for the general case -- sorry about that!

When I said 'boring and tedious' I just mean that there's no magic sauce to our approach; it's all grunt work & sweat. Your deep copy approach is the one we take, which works fine for colours as I think you've probably found. It doesn't work when one of those deep copy variables contains a handle. That's what I was trying (and maybe failing) to explain in an earlier post.

So yes, when I'm copying a swatch/colour, I effectively do a switch on the 'kind' (there are a lot of switch-statements in this code if I recall). kPattern, kCustomColor  & kGradient are the three that have additional headaches, because they have handles. For the latter two, I create a new custom colour or gradient in the new document manually, then configure them using the source's values. This may require querying the handle in the source document for information to use when creating the new handle in the destination. I remember gradients are a bit of a pain because you have to iterate over all the gradient stops and copy them into the new gradient. Hmm, looking at the code, I just noticed a potential bug -- apparently gradient stops can have custom colours. Since that involves another handle and I'm not taking care of that, I'm pretty sure it means a crash if one of my users puts one in a gradient and then tries to copy it between documents. What a mess this is; would it have killed Adobe to include an API that does this for us? I'm fairly certain we're just repeating code they have tucked away in some utility class somewhere.

I thought there was an easy fix for patterns, but apparently I was wrong. Still, it's not so bad; you basically get the pattern art from the source, create a new pattern in the destination, and set that new pattern's art to what you got from the source.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

I wasn't suggesting you did it manually. I said it seemed you could achieve what you wanted to do manually, but then said that you should be able to do the same thing using the SDK.

I am a bit confused when you say that only the swatch updates and not the document when you are copying swatches of all kinds including  kThreeColor, kFourColor swatches. As far as I know only spot colors (and possibly gradients) will update in the document when you change them in the swatch. Are you expecting process color swatches to update in the document too?

I think you need to break the task down into steps (for example):

Step 1:

With a single document open, when you select your menu item, find an existing spot color swatch in the current document and change the color. Does the document update?

Step 2:

With two documents open, when you select your menu item, find an existing spot color swatch in one document and change the same spot color swatch in the other document to be the same color.

Step 3:

With the source document open, when you select your menu item, open each destination document in turn and update the swatches.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

I've never actually used Illustrator prior to working on this project, and as such have no idea what it can and can't do, or how it should or shouldn't behave when tasked with this. In the source document, I see that the swatch colors in swatches are, according to the swatch options window, of type Process Color, Global, and RGB color mode. In the color mode dropdown there are six options (Grayscale, RGB, HSB, CMYK, Lab and Web-Safe RGB). These seem to correspond to the flags set on the AIColor representation of same, and for what it's worth I do not think they are spot colors. There are a set of documents which all use the same color palette for many elements within each document and they (we) are hoping to be able to automate the update of those colors across the document set, by providing the source palette to the operation.

I too am confused when I see the swatch color update in swatches but there is no update to the document itself. Your suggestion to perform an update within the source document is appreciated.

Your example step 1 was unable to be completed successfully. As prior, the swatches view of the color updates, but not the document view of it. That swatch color can no longer be adjusted in Illustrator, such that the document view of it updates, whereas all other colors can. So the behavior here is the same as when attempting to copy it into a destination document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

In the swatch options window, the "Color Type" dropdown is either "Process Color" or "Spot Color". If you use a spot color to color art, the color of the art will change when you change the spot color in the swatch palette. If you color art using a process color and then later change that process color to a spot color, the art will not update when you change the spot color swatch. If your documents only contain process colors, you would have to go through the individual art objects to change the colors.

"That swatch color can no longer be adjusted in Illustrator, such that the document view of it updates, whereas all other colors can."

Are you saying that the process colors in the doument update when you update the process color swatches? I have never seen that behaviour before. If art is selected, then the color will change to whatever you select in the swatch panel.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

Sorry, I missed the Global setting. Yes, if the process color has the Global setting checked then it will behave like a spot color.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

Alright, do you mean that I will need to iterate the document's art objects in order to adjust their colors since their swatches are global process colors?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

No, if they are global process colors then just updating the swatch color should work. What is your code for Step 1 (just changing a swatch color in the current document)? Is the Global option still set after your code runs?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 26, 2017 Oct 26, 2017

Copy link to clipboard

Copied

Here is the code I isolated for step 1 of your earlier suggestion. It behaves as previously described.

ASErr SwatchUpdaterPlugin::LoadMasterSwatchPalette()

{

     ASErr result = kNoErr;

     this->fMasterSwatchList = NULL;

     result = sAISwatches->GetSwatchList(NULL, &fMasterSwatchList);

     if (result) return result;

     sAIUser->MessageAlert(ai::UnicodeString("Master palette selected with " +

          std::to_string(int(sAISwatches->CountSwatches(NULL))) +

          " swatch(es)."));

     return result;

}

The routine you asked for the code from:

ASErr result = kNoErr;

ASInt32 count = this->CountOpenDocuments();

if (count == 1)

{     // populates swatchList from current document's swatches

     result = this->LoadMasterSwatchPalette();

     if (result) return result;

}

// select relevant color profile.

AIColorProfile rgb, cmyk, gray;

result = sAIDocument->GetDocumentProfiles(&rgb, &cmyk, &gray);

ai::UnicodeString name;

if (rgb)

result = sAIOverrideColorConversion->GetProfileName(rgb, name);

else if (cmyk)

result = sAIOverrideColorConversion->GetProfileName(cmyk, name);

else

result = sAIOverrideColorConversion->GetProfileName(gray, name);

string s = name.as_Roman();

short colorModel;

result = sAIDocument->GetDocumentColorModel(&colorModel);

// above code appears unrelated to the function's remainder

// attempt to find a color in the swatch palette

ai::UnicodeString colorName("WM_Black");

AICustomColorHandle colorHandle;

AICustomColor color;

// find the color name in the doc's swatch

result = sCustomColor->GetCustomColorByName(colorName, &colorHandle);

if (result)

{

     sAIUser->MessageAlert(ai::UnicodeString("Color not found"));

}

else

{

     result = sCustomColor->GetCustomColor(colorHandle, &color);

     AIDocumentHandle document = NULL; // current document

     result = sAIDocument->GetDocument(&document);

     AISwatchListRef swatchList;

     result = sAISwatches->GetSwatchList(document, &swatchList);

     AISwatchRef swatch = NULL;

     swatch = sAISwatches->GetSwatchByName(swatchList, colorName);

     if (swatch)

     {

          sAIUser->MessageAlert(ai::UnicodeString("Swatch found"));

          result = sAISwatches->SetSwatchName(swatch, ai::UnicodeString("Test"));

          AIColor aiColor;

          color.c.rgb.red = 0.7685;

          color.c.rgb.green = 0.051;

          color.c.rgb.blue = 0.051;

          color.flag = kCustomRegistrationColor;

          color.kind = kCustomThreeColor;

          result = sCustomColor->NewCustomColor(&color, colorName, &colorHandle);

          aiColor.kind = kCustomColor;

          aiColor.c.c.tint = 0.0f;

          aiColor.c.c.color = colorHandle;

          result = sAISwatches->SetAIColor(swatch, &aiColor);

     }

     else

     {

          sAIUser->MessageAlert(ai::UnicodeString("Swatch not found"));

     }

}

After this code runs, the swatch attributes remain unchanged but manually adjusting sliders no longer updates the document.

Thanks for helping me get to the bottom of this Leo.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 27, 2017 Oct 27, 2017

Copy link to clipboard

Copied

I haven't done much with swatches, but having experimented with some code, it seems that both spot colors and global process colors use custom color handles. These swatches reference the custom colors in the document. To achieve what you want, you don't actually have to do anything with the swatches, you just change the color values of the custom colors in the document:

        AICustomColorHandle colorHandle = NULL;

        sCustomColor->GetCustomColorByName(ai::UnicodeString("WM_Black"),&colorHandle);

        if (NULL != colorHandle)

        {

            AICustomColor color;

            sCustomColor->GetCustomColor(colorHandle,&color);

            switch (color.kind)

            {

                case kCustomThreeColor:

                    color.c.rgb.red = 0.7685;

                    break;

                case kCustomFourColor:

                    color.c.f.magenta = 0.3;

                    break;

            }

            sCustomColor->SetCustomColor(colorHandle,&color);

        }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 27, 2017 Oct 27, 2017

Copy link to clipboard

Copied

LATEST

I was able to craft the entire solution once this key piece of understanding was received.

Thank you!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines