Skip to main content
Known Participant
March 7, 2006
Question

Problem Programmatically Placing Images with Placed or Raster Suites

  • March 7, 2006
  • 2 replies
  • 1160 views
We have some code that currently uses the Raster suite to place art. The code actually works but it seems to make Illustrator unstable. If you "undo" following the art placement, Illustrator crashes without any warning. The call that causes problems is "AIRaster->ResolveRasterLink". If this call is omitted, then "undo" does not crash the application. Of course, the image data isn't read either.

The latest version of the API docs (the HTML version not the PDF version) has the following comment on "AIRaster->SetRasterLink":

Direct linking of images is deprecated but still supported. All linked objects should be created using the AIPlacedSuite.

So I tried using the AIPlaced suite instead. Specifically, I used the "AIPlaced->ExecPlaceRequest" method. I would really like to use the kVanillaPlace value of "AIPlaceRequestData.m_lPlaceMode". This seems to half work but the ExecPlaceRequest method returns an error value and method calls with the m_hNewArt handle give an error in Illustrator about a pure virtual method call. I've also tried the kForceReplace and kQueryReplace modes but they don't work either. The kCreateNewArt mode seems to work but it doesn't read any data. It seems to just be a call to AIArt->NewArt.

Can anyone confirm or deny the behavior I'm seeing with either or both of AIRaster or AIPlaced? Does anyone have a workaround?
This topic has been closed for replies.

2 replies

Known Participant
May 5, 2006
I can't get your code to work under CS. We are currently stuck using CS because CS2 seems to have a problem with overlapping file extensions (i.e. when you have two file filters that handle file extension ".foo"). It seems like the crucial bit in the code above is the new argument added in CS2 to this call:

sAIArt->UpdateArtworkLink(art, true, &updated);

The second argument is supposed to force a reload of the artwork. This reload doesn't seem to happen in CS. Anyone know how to get around this problem for CS? Or, even better, does anyone have overlapping file extensions working in CS2?
Participant
March 8, 2006
Here's some code that ought to work with AICS2. I haven't tried undo though:


AIArtHandle art;

AIErr result = sAIArt->NewArt(kPlacedArt, where, prep, &art);

CHECK(!result);



// give it some meaningful bounds, that will be centered on the origin in case the file

// does not exist

AIRealRect bbox = {0,72,72,0};

result = sAIPlaced->SetPlacedBoundingBox(art, &bbox);

CHECK (!result);

// we also need an identity matrix

RealMatrix identity;

result = sAIPlaced->SetPlacedMatrix(art, &identity);

CHECK (!result);



if (file.Exists(false))

{

// this can fail for one of three reasons:

// 1) The file doesn't exist (fnfErr == -43), but we checked already that it does

// 2) The file is not an EPS (badEPSFileErr == 376)

// 3) Some other fatal error

result = sAIPlaced->SetPlacedFileSpecification(art, file);

if (result)

{

// Let's assume it is not an EPS and try to load it as a non-EPS placed file.

// This next call is needed in order to indicate that the placed object is not an EPS.

// Ideally it wouldn't be necessary but unfortunately at present it is.

AIArtHandle group;

result = sAIPlaced->SetPlacedObject(art, &group);

CHECK (!result);

// Another thing that ideally would not be necessary is applying a vertical flip in

// the transformation matrix.

RealMatrix flip = RealMatrix::Scale(1,-1);

result = sAIPlaced->SetPlacedMatrix(art, &flip);

CHECK (!result);

// This should not fail

AIBoolean updated;

result = sAIArt->UpdateArtworkLink(art, true, &updated);

CHECK (!result);

}

}



// now translate the object to be centered on the origin

AIRealRect bounds;

result = sAIArt->GetArtBounds(art, &bounds);

CHECK (!result);

RealMatrix matrix = RealMatrix::Translation(-(bounds.left+bounds.right)/2, -(bounds.top+bounds.bottom)/2);

result = sAIPlaced->ConcatPlacedMatrix(art, &matrix);

CHECK (!result);