#include <ai_grad.h>
Public Member Functions | |
AIGradientProcessor () | |
virtual | ~AIGradientProcessor () |
BOOL | BeginGradient () |
Allows the gradient processor to intialize itself for a new gradient signalled by the BeginGradient comment. | |
BOOL | DecodeBd (AI5EPSFilter &filter) |
Processes the gradient definition start operator which tells us how many colours are in it and what its name is. | |
BOOL | DecodeBS (AI5EPSFilter &filter) |
Processes the gradient stop operator (indicating a step in the ramp). | |
BOOL | DecodeBh (AI5EPSFilter &filter) |
The Bh operator adds a highlight to a fill. In Camelot we interpret this as a conical fill. | |
BOOL | EndGradient (AI5EPSFilter &filter) |
Allows the gradient processor to complete the gradient signalled by the EndGradient comment. | |
AI5Gradient * | FindGradient (const StringBase &name) |
Once the gradient definitions have been read, gradient instances can be created using the name to identify the gradient "style". | |
Private Member Functions | |
BOOL | Approx (const double &d1, const double &d2) |
This is used to determine whether the position of one gradient stop is equivalent to another during import, mainly for working out which stops are at the start and the end. | |
Private Attributes | |
List | mGradFills |
BOOL | mbGradFillTooComplex |
AI5Gradient * | mpCurrentFill |
INT32 | mMidPoint |
INT32 | mLastRampPoint |
Definition at line 174 of file ai_grad.h.
|
Definition at line 148 of file ai_grad.cpp. 00148 : 00149 mbGradFillTooComplex(FALSE), 00150 mpCurrentFill(0) 00151 { 00152 // The last ramp point is set to 101, since this is effectively a 00153 // counter from 100 down to 0. 00154 mMidPoint = 0; 00155 mLastRampPoint = 101; 00156 }
|
|
Definition at line 158 of file ai_grad.cpp. 00159 { 00160 mGradFills.DeleteAll(); 00161 00162 delete mpCurrentFill; 00163 mpCurrentFill = 0; 00164 }
|
|
This is used to determine whether the position of one gradient stop is equivalent to another during import, mainly for working out which stops are at the start and the end.
Definition at line 459 of file ai_grad.cpp.
|
|
Allows the gradient processor to intialize itself for a new gradient signalled by the BeginGradient comment.
Definition at line 181 of file ai_grad.cpp. 00182 { 00183 ENSURE( mpCurrentFill == NULL, "mpCurrentFill is not NULL"); 00184 00185 // Found the start of a gradient definition - prepare to read in the 00186 // definition... 00187 mpCurrentFill = new AI5Gradient; 00188 00189 if ( !mpCurrentFill ) 00190 return FALSE; 00191 00192 return TRUE; 00193 }
|
|
Processes the gradient definition start operator which tells us how many colours are in it and what its name is.
Definition at line 211 of file ai_grad.cpp. 00212 { 00213 if ( !mpCurrentFill ) 00214 return FALSE; 00215 00217 // Name, type, and number of steps in gradient fill 00219 INT32 colours = 0; 00220 INT32 type = 0; 00221 00222 if (!filter.GetStack().Pop(&colours) || 00223 !filter.GetStack().Pop(&type) || 00224 !filter.GetStack().Pop(&mpCurrentFill->Name)) 00225 // Error in syntax 00226 return FALSE; 00227 00228 // Translate fill type 00229 switch (type) 00230 { 00231 case 0: mpCurrentFill->IsRadial = FALSE; break; 00232 case 1: mpCurrentFill->IsRadial = TRUE; break; 00233 default: return FALSE; 00234 } 00235 00236 return TRUE; 00237 }
|
|
The Bh operator adds a highlight to a fill. In Camelot we interpret this as a conical fill.
Arguments to the Bh operator are as follows: xHilight yHilight These arguments specify the hilight placement, in x and y offsets from the gradient vector origin. angle This argument is the angle to the hilight point, measured counterclockwise from the x axis. length This argument is the distance of the hilight from the origin, expressed as a fraction of the radius a value between 0 and 1. Definition at line 409 of file ai_grad.cpp. 00410 { 00412 // read the arguments from the stack 00414 00415 INT32 nAngle = 0; 00416 double dLength = 0.0; 00417 DocCoord hilight; 00418 00419 if ( !filter.GetStack().Pop(&dLength) || !filter.GetStack().Pop(&nAngle) || 00420 !filter.GetStack().PopCoordPair(&hilight) ) 00421 return FALSE; 00422 00424 // Check if these are values we can handle 00426 00428 // Attach the highlight details so we can work out what to do later 00429 // but if there's already a highlight ignore this one 00431 /* 00432 00433 Won't do this for now 00434 00435 00436 mpCurrentHighlight = new AI5Gradient::Highlight( nAngle, dLength, hilight ); 00437 */ 00438 return TRUE; 00439 }
|
|
Processes the gradient stop operator (indicating a step in the ramp).
Definition at line 252 of file ai_grad.cpp. 00253 { 00254 // Decode colour/step definition 00255 INT32 rampPoint = 0, midPoint = 0; 00256 00257 if ( !filter.GetStack().Pop(&rampPoint) || !filter.GetStack().Pop(&midPoint) ) 00258 return FALSE; 00259 00260 // Check if these are values we can handle 00261 // (We still import an approximation of the fill even if not) 00262 if ( midPoint > 100 || midPoint < 0 || rampPoint < 0 || rampPoint > 100 ) 00263 { 00264 return FALSE; 00265 } 00266 00267 // Work out what sort of colour this is - CMYK or B&W tint 00268 INT32 colorStyle; 00269 if ( !filter.GetStack().Pop(&colorStyle) ) 00270 return FALSE; 00271 00272 DocColour newColour; 00273 00274 switch ( colorStyle ) 00275 { 00276 case 0: // grey 00277 { 00278 double dTint( 0.0 ); 00279 if ( !filter.GetStack().Pop(&dTint) ) 00280 return FALSE; 00281 00282 // Make a colour from this 00283 INT32 intensity = (INT32) (dTint * 255.0); 00284 newColour.SetRGBValue( intensity, intensity, intensity ); 00285 break; 00286 } 00287 00288 case 1: // CMYK 00289 { 00290 PColourCMYK col; 00291 if (!filter.GetStack().PopColour(&col, TINT_NONE)) 00292 return FALSE; 00293 00294 // Set up the colour with what we have. 00295 newColour.SetCMYKValue( &col ); 00296 00297 break; 00298 } 00299 00300 case 2: // RGB 00301 { 00302 INT32 red, green, blue; 00303 if (!filter.GetStack().PopColourRGB (&red, &green, &blue, TINT_NONE)) 00304 return FALSE; 00305 00306 // remove the CMYK colour info. 00307 (filter.GetStack()).Discard (4); 00308 newColour.SetRGBValue (red, green, blue); 00309 break; 00310 } 00311 00312 case 3: // CMYK custom 00313 { 00314 PColourCMYK col; 00315 FIXEDPOINT tint; 00316 String_64 name; 00317 if ( !filter.GetStack().PopColour( &col, TINT_ILLUSTRATOR, &tint, &name ) ) 00318 return FALSE; 00319 00320 newColour.SetCMYKValue( &col ); 00321 00322 break; 00323 } 00324 00325 case 4: // RGB custom 00326 { 00327 INT32 red, green, blue; 00328 FIXEDPOINT tint; 00329 String_64 name; 00330 00331 // remove the 'type' flag (is always 1 for RGB) 00332 filter.GetStack().Discard (1); 00333 00334 if (!filter.GetStack().PopColourRGB (&red, &green, &blue, 00335 TINT_ILLUSTRATOR, &tint, &name)) 00336 return FALSE; 00337 00338 (filter.GetStack()).Discard (4); 00339 newColour.SetRGBValue (red, green, blue); 00340 00341 break; 00342 } 00343 default: 00344 break; 00345 } 00346 00347 00349 // add the colour to the ramp 00351 00352 double dPos = double(rampPoint) / double(100.0); 00353 00354 if ( mpCurrentFill ) 00355 { 00356 if ( !mpCurrentFill->mpCurrentRamp ) 00357 { 00358 mpCurrentFill->mpCurrentRamp = new ColourRamp; 00359 if ( ! mpCurrentFill->mpCurrentRamp ) 00360 { 00361 return FALSE; 00362 } 00363 } 00364 00365 mpCurrentFill->mpCurrentRamp->AddEntry( static_cast<float> ( dPos ), &newColour ); 00366 } 00367 00368 // Set the midpoint if this point is nearer to the start than the stored mid-point. 00369 // The midpoint nearest to the 0% ramp point is used, as there should only be one 00370 // midpoint if Xara X's profiling is going to cope with it, and the last midpoint in 00371 // an Illustrator gradient should always be ignored. 00372 if (rampPoint < mLastRampPoint) 00373 { 00374 mMidPoint = midPoint; 00375 mLastRampPoint = rampPoint; 00376 } 00377 00378 return TRUE; 00379 }
|
|
Allows the gradient processor to complete the gradient signalled by the EndGradient comment.
Definition at line 480 of file ai_grad.cpp. 00481 { 00482 ENSURE( mpCurrentFill != NULL, "mpGradFill is NULL"); 00483 00484 // The end of the definition - lose the rampant '[' from the input stream. 00485 EPSCommand Cmd; 00486 if (!filter.GetStack().PopCmd(&Cmd) || (Cmd != EPSC_ArrayStart)) 00487 { 00488 // if it isn't what we're hoping for, ignore it 00489 filter.GetStack().Push( Cmd ); 00490 } 00491 00493 // an n-stage multi-stage fill in camelot is divided into n - 2 ramp items 00494 // and the start and end colours of the fill. 00495 // When creating the fill we have just added ramp items, so we need to pick 00496 // off the first and last for the start and end colours. 00498 00499 if ( mpCurrentFill->mpCurrentRamp ) 00500 { 00501 // (ChrisG 3/4/2001) Gradient stops are now always removed from the list if they are 00502 // used as a start or end colour. There was a check to make sure they were near the 00503 // end, which often failed, leading to additional stops at the ends. 00504 00505 // first the start colour 00506 ColRampItem* pFirstItem = reinterpret_cast<ColRampItem*>( mpCurrentFill->mpCurrentRamp->GetHead() ); 00507 if ( pFirstItem ) 00508 { 00509 // Take the first colour out of the ramp, as this is represented by the start colour 00510 mpCurrentFill->StartColour = pFirstItem->GetColour(); 00511 00512 // if the first ramp item isn't at the start of the fill, leave it as 00513 // part of the ramp and make the start the same colour 00514 if ( Approx( pFirstItem->GetPosition(), 0.0) || 00515 Approx( pFirstItem->GetPosition(), 100.0)) 00516 { 00517 mpCurrentFill->mpCurrentRamp->RemoveHead(); 00518 } 00519 } 00520 00521 // then the end colour 00522 ColRampItem* pLastItem = reinterpret_cast<ColRampItem*>( mpCurrentFill->mpCurrentRamp->GetTail() ); 00523 if ( pLastItem ) 00524 { 00525 // Take the last colour out of the ramp, as this is represented by the end colour 00526 mpCurrentFill->EndColour = pLastItem->GetColour(); 00527 00528 // if the first ramp item isn't at the start of the fill, leave it as 00529 // part of the ramp and make the start the same colour 00530 if ( Approx( pLastItem->GetPosition(), 0.0) || 00531 Approx( pLastItem->GetPosition(), 100.0)) 00532 { 00533 mpCurrentFill->mpCurrentRamp->RemoveTail(); 00534 } 00535 } 00536 } 00537 00538 // set the mid-point, for the profiling. 00539 mpCurrentFill->midPoint = mMidPoint; 00540 00541 // add the current fill to our list. 00542 mGradFills.AddTail( mpCurrentFill ); 00543 00544 // We're done with this fill. 00545 mpCurrentFill = NULL; 00546 00547 // reset the profiling variables. 00548 mMidPoint = 0; 00549 mLastRampPoint = 101; 00550 00551 return TRUE; 00552 }
|
|
Once the gradient definitions have been read, gradient instances can be created using the name to identify the gradient "style".
Definition at line 569 of file ai_grad.cpp. 00570 { 00571 // First find this named gradient fill 00572 AI5Gradient* pGradient = (AI5Gradient *) mGradFills.GetHead(); 00573 00574 while ( pGradient ) 00575 { 00576 if ( pGradient->Name == name ) 00577 // This is the one we want! 00578 break; 00579 00580 // Try the next one 00581 pGradient = (AI5Gradient *) mGradFills.GetNext(pGradient); 00582 } 00583 00584 return pGradient; 00585 }
|
|
|
|
|
|
|
|
|
|
|