1#include "AOI_Document.h"
2#include "AOI_Instance.h"
3#include "../GDocument.h"
4#include "../GInstance.h"
5#include "ghostscript.h"
6#include <ACPL/FileStream.h>
7#include <ACPL/Utilities.h>
8#include "../PDF/Error.h"
10#include "../GVector.h"
12#include "../GPlaceHolder.h"
13#include <ACPL/Multithreading.h>
17using namespace aur::PDF;
18using namespace aur::ACPL;
26static bool FillObjectDetails( Object*
object, PDF::Point mouse,
bool stroke, Document* doc, AOI_Color* outHitColor )
31 if( object->GetType() == gGroupType )
33 Group* grp =
dynamic_cast<GroupPtr
>(object);
35 child = grp->GetFirstChild();
38 while( child && !ret )
40 ret = FillObjectDetails( child, mouse, stroke, doc, outHitColor );
41 child = grp->GetNthChild( ++index );
45 if(object->GetType() == gPlaceHolderType)
47 SymbolPtr sym =
dynamic_cast<SymbolPtr
>( object );
48 if( sym && sym->GetObject() )
50 return FillObjectDetails( sym->GetObject() ,mouse ,stroke, doc, outHitColor );
53 StylePtr style = NULL;
54 ColorSpaceObject* space = NULL;
55 VectorPtr vector =
dynamic_cast<VectorPtr
>(object);
57 style = ( stroke && vector->GetStrokeStyle() ) ? vector->GetStrokeStyle() : vector->GetFillStyle();
60 SymbolPtr symbol =
dynamic_cast<SymbolPtr
>(object);
62 style = (StylePtr)symbol->GetColor();
65 RasterPtr raster =
dynamic_cast<RasterPtr
>(object);
69 BitmapPtr bitmap = raster->GetBitmap();
70 Mapping invertMap = raster->mapping();
74 space = raster->GetColorSpace();
76 bitmap->GetPixel(int32_t(mouse.x), int32_t(mouse.y), color);
79 outHitColor->space = AOI_ColorSpacePtr( color.space );
80 ::memcpy( outHitColor->channel, color.channel, space->NrOfComponents() *
sizeof( uint16_t ) );
87 switch(style->GetType())
89 case PDF::Style::eSolid:
91 SolidPtr color =
dynamic_cast<SolidPtr
>(style);
94 space = color->GetSpace();
95 outHitColor->space = AOI_ColorSpacePtr( space );
96 ::memcpy( outHitColor->channel, c.channel, outHitColor->space->NrOfComponents() *
sizeof( uint16_t ) );
99 case PDF::Style::ePattern:
101 case PDF::Style::eShading:
103 ShadingSpacePtr shade =
dynamic_cast<ShadingSpacePtr
>( style );
104 space = shade->GetColorSpace();
106 if( shade->GetColor( mouse.x, mouse.y, col ) == false )
111 outHitColor->space = AOI_ColorSpacePtr( col.space );
112 ::memcpy( outHitColor->channel, col.channel, space->NrOfComponents() *
sizeof( uint16_t ) );
120 if( space->ResourceType() == IndexColorSpace::eResourceType )
122 IndexColorSpace* indexed =
dynamic_cast<IndexColorSpace*
>( space );
124 c.space = indexed->GetBase();
125 indexed->GetColor( outHitColor->channel[0] >> 8, c.channel );
127 outHitColor->space = AOI_ColorSpacePtr( c.space );
128 ::memcpy( outHitColor->channel, c.channel, space->NrOfComponents() *
sizeof( uint16_t ) );
131 return space != NULL;
145 mSpotColorList( NULL ),
146 mUseSimpleRenderer( false ),
151 mInstance = instance->mInstance;
154::ExceptionCode AOI_Document::ConvertPStoPDF(
const FileSpec& pathToPS,
const FileSpec& pathToPDF )
156 static CriticalSection sPSAccess;
159 ::ExceptionCode err = NoError;
167 PS2PDF( pathToPS, pathToPDF, psError, psFonts, mInstance );
168 if( psError.GetLength() )
169 mInstance->Error( 1, 3, psError );
170 if( psFonts.GetLength() )
171 mInstance->Error( 2, 4, psFonts );
173 catch( aur::ExceptionCode psErr )
196void AOI_Document::Open(
const aur::ACPL::FileSpec& path,
const char* ownerPassword,
const char* userPassword )
203 mDocument =
new Document( NULL, mInstance );
206 FileStream stream( path, eReadPermission );
207 if( stream.GetLength() == 0 )
209 mDocument->GetInstance()->Error( 1, 1,
"File is 0 bytes long" );
215 mDocument->GetInstance()->Error( 1, 2,
"Error while opening file" );
219 Document::DetermineFileType( path, fileType );
220 if( mUseSimpleRenderer && ( fileType ==
"tif" || fileType ==
"jpg" ) )
223 Document::GetInfo( path, info );
224 if( info.space != NoSpace &&
225 info.pages->size() == 1 &&
226 ( info.space != INDEXED( GraySpace ) || fileType !=
"tif" ) &&
227 ( info.reference == NULL || (info.space&IndexedSpaces)!=IndexedSpaces ) &&
228 !strstr( info.description,
"+" ) )
230 mImageSpec =
new FileSpec( path );
231 mDocument->GetPage()->SetDimensions( info.pages->front() );
235 mUseSimpleRenderer =
false;
237 if( fileType ==
"eps" )
239 mPDFSpec =
new FileSpec();
240 mPDFSpec->CreateTemporary( NULL,
"pdf" );
242 aur::ExceptionCode psErr = ConvertPStoPDF( path, *mPDFSpec );
243 if( psErr == NoError )
244 mDocument->OpenFile( *mPDFSpec, ownerPassword, userPassword );
246 mDocument->GetInstance()->Error( 100, uint16_t(psErr),
"PostScript Error" );
252 mDocument->OpenFile( path, ownerPassword, userPassword );
254 catch( aur::ExceptionCode plugErr )
256 if( plugErr == ErrUserCanceled )
257 mDocument->GetInstance()->Error( 100, ErrUserCanceled,
"Plugin User Canceled" );
259 mDocument->GetInstance()->Error( 100, uint16_t(plugErr),
"Plugin Error" );
263 mDocument->GetInstance()->Error( 100, 1,
"Plugin fatal error" );
270 Open( FileSpec( path ) );
273AOI_Document::~AOI_Document()
280 delete[] mSpotColorList;
291 return mDocument->GetPageCount();
306 mDocument->SetCurrentPage( pageNr );
307 return AOI_PagePtr( mDocument->GetPage( pageNr ) );
323 ObjectPtr o = ObjectPtr(
object );
324 bool res = mDocument->TraverseNext( o );
339 return AOI_ColorSpacePtr( mDocument->GetDocumentColorSpace() );
352 return AOI_ColorSpacePtr( mDocument->GetLabColorSpace() );
365 return AOI_ColorSpacePtr( mDocument->GetDeviceGrayColorSpace() );
378 return AOI_ColorSpacePtr( mDocument->GetDeviceRGBColorSpace() );
391 return AOI_ColorSpacePtr( mDocument->GetDeviceCMYKColorSpace() );
394static bool StyleIsBW( StylePtr style )
397 SolidPtr color =
dynamic_cast<SolidPtr
>(style);
398 if( color && ( color->GetSpace()->Space() & GraySpace ) != GraySpace )
402 color->GetColor( col );
403 if( ( col.space->Space() & DeviceNSpace ) == DeviceNSpace || ( col.space->Space() & CMYKSpace ) == CMYKSpace )
405 for( uint32_t chan=0; chan != col.space->NrOfComponents(); ++chan )
406 if( ( ::strcmp( col.space->ChannelName( chan ),
"Black" ) != 0 &&
407 ::strcmp( col.space->ChannelName( chan ),
"White" ) != 0 )
408 && col.channel[chan] != 0 )
411 else if( ( col.space->Space() & RGBSpace ) == RGBSpace )
413 if ( ! ( ( col.channel[0] == col.channel[1] ) && ( col.channel[1] == col.channel[2] ) ) )
422static void ParseLayer( ObjectPtr obj, PagePtr page,
bool& isBW )
427 VectorPtr vector = NULL;
430 if( ( vector =
dynamic_cast<VectorPtr
>(obj) ) )
432 isBW = ( StyleIsBW( vector->GetFillStyle() ) && StyleIsBW( vector->GetStrokeStyle() ) );
433 obj = obj->GetNext();
435 else if( obj->GetType() == gGroupType )
437 ParseLayer( ((GroupPtr)obj)->GetFirstChild(), page, isBW );
438 obj = obj->GetNext();
440 else if( obj->GetType() == gPlaceHolderType || obj->GetType() == gSymbolType )
442 ObjectPtr child = NULL;
443 if( obj->GetType() == gPlaceHolderType )
444 child = ((PlaceHolderPtr)obj)->GetObject();
446 child = ((SymbolPtr)obj)->GetObject();
448 ParseLayer( child, page, isBW );
449 obj = obj->GetNext();
452 obj = obj->GetNext();
454 while( obj && isBW );
467 for( uint32_t i = 0 ; i <
GetPageCount() && isBW ; i++ )
469 PagePtr page = mDocument->GetPage( i );
470 for( LayerPtr layer = page->GetFirstLayer() ; layer && isBW; layer = (LayerPtr)layer->GetNext() )
472 ObjectPtr obj = layer->GetFirstChild();
473 ParseLayer( obj, page, isBW );
479bool static CheckFonts(
const std::vector<FontFile*>& allFonts, ObjectPtr obj )
481 PDF::TextPtr textObject =
dynamic_cast<PDF::TextPtr
>( obj );
482 if( textObject && textObject->Visible() )
485 textObject->GetProperties( props );
486 for(
auto& nFont : allFonts )
487 if( ::stricmp( props.style.fontName, nFont->GetName() ) == 0 )
492 GroupPtr group =
dynamic_cast<GroupPtr
>( obj );
495 for( ObjectPtr child = group->GetFirstChild(); child; child = child->GetNext() )
496 if( CheckFonts( allFonts, child ) )
510 bool fontExists =
false;
512 uint32_t currentPage = mDocument->GetCurrentPage();
514 std::vector<FontFile*> allEmbededFonts;
516 indexPage = currentPage;
517 for( uint32_t i = 0; i < mDocument->GetPageCount(); ++i )
519 if( indexPage >= mDocument->GetPageCount() )
521 mDocument->SetCurrentPage( indexPage );
522 allEmbededFonts = mDocument->FontUsage();
523 fontExists = !allEmbededFonts.empty();
524 if( fontExists && !onlyUsed )
527 mDocument->SetCurrentPage( currentPage );
528 if( fontExists && onlyUsed )
531 for( uint32_t nPage = 0; nPage < mDocument->GetPageCount() && !fontExists; nPage++ )
532 for( LayerPtr layer = mDocument->GetPage( nPage )->GetFirstLayer(); layer && !fontExists; layer = layer->GetNextLayer() )
533 for( ObjectPtr obj = layer->GetFirstChild(); obj && !fontExists; obj = obj->GetNext() )
534 if( CheckFonts( allEmbededFonts, obj ) )
557 mDocument->SavePDF( path,
false, path.FileTitle() );
559 catch( aur::ExceptionCode err )
579 delete[] mSpotColorList;
580 mSpotColorList = NULL;
582 std::vector<SpotColorName> list;
583 DeviceN* devn = NULL;
585 while( ( devn = (DeviceN*)mDocument->TraverseCommitedResources( DeviceN::eResourceType, devn ) ) != NULL )
587 for( j = 0; j != devn->NrOfComponents(); ++j )
589 SpotColorName n = devn->ChannelName( j );
590 bool found = ::strcmp( n,
"None" ) == 0 || ::strcmp( n,
"All" ) == 0;
594 for( i = 0; i != list.size() && ::stricmp( n, list[i] ); ++i )
596 if( i == list.size() )
604 mSpotColorList =
new SpotColorName[ list.size() + 1 ];
605 for( i = 0; i != list.size(); ++i )
606 mSpotColorList[i] = list[i];
607 mSpotColorList[i] = NULL;
610 return mSpotColorList;
638 what.u.part.stroke =
true;
639 what.u.part.fill =
true;
640 int16_t snap = mDocument->GetInstance()->GetSnapDistance();
641 mDocument->GetInstance()->SetSnapDistance( snapDistance );
642 ObjectPtr hitObject = mDocument->HitTest( fp, what, 32767 );
643 stroke = what.u.part.stroke;
644 mDocument->GetInstance()->SetSnapDistance( snap );
645 if( hitObject && outHitColor )
650 FillObjectDetails( hitObject, mouse, stroke, mDocument, outHitColor );
655void AOI_Document::SimpleImage()
657 mUseSimpleRenderer =
true;
665 mDocument->CloseFile( keepVM, createDefaults );
668AOI_DocumentInfo::AOI_DocumentInfo() :
673 space( AOI_NoSpace ),
688 exposureBiasValue( 0 )
692bool AOI_DocumentInfo::GetInfo(
const FileSpec& path )
696 aur::PDF::Document::Info info;
697 PDF::Document::GetInfo( path, info );
699 fileSize = info.fileSize;
700 pageCount = info.pages->size();
701 width = info.pages->front().w;
702 height = info.pages->front().h;
703 space = AOI_ColorSpaceEnum( info.space );
704 encrypted = info.encrypted;
705 denyPrint = info.denyPrint;
706 denyChange = info.denyChange;
707 denyCopy = info.denyCopy;
708 denyNotes = info.denyNotes;
711 fileType = info.fileType;
712 description = info.description ? info.description :
"";
713 artist = info.artist;
714 software = info.software;
717 orientation = info.orientation;
718 xResolution = info.xResolution;
719 yResolution = info.yResolution;
720 pixelWidth = info.pixelWidth;
721 pixelHeight = info.pixelHeight;
722 resolutionUnit = info.resolutionUnit;
723 dateTime = info.dateTime;
724 exposureTime = info.exposureTime;
725 Fnumber = info.Fnumber;
726 ISOSpeedRating = info.ISOSpeedRating;
727 exposureBiasValue = info.exposureBiasValue;
728 return fileSize != 0;
AOI_ColorSpacePtr GetLabColorSpace() const
bool TraverseNext(AOI_Object *&) const
bool FontExists(bool onlyUsed) const
AOI_ColorSpacePtr GetDocumentColorSpace() const
AOI_ColorSpacePtr GetDeviceRGBColorSpace() const
uint32_t GetPageCount() const
SpotColorName * GetSpotColorList()
void CloseFile(bool keepVM, bool createDefaults)
ExceptionCode SaveAsPDF(const aur::ACPL::FileSpec &path)
AOI_Document(AOI_Instance *)
AOI_Object * HitTest(AOI_Point p, int16_t snapDistance, bool &stroke, AOI_Color *outColor=NULL)
AOI_ColorSpacePtr GetDeviceGrayColorSpace() const
void Open(const aur::ACPL::FileSpec &path, const char *ownerPassword=NULL, const char *userPassword=NULL)
AOI_ColorSpacePtr GetDeviceCMYKColorSpace() const
bool BlackAndWhiteDoc() const
AOI_Page * GetPage(uint32_t) const
Instance of the AOI engine.
Base class for all graphic objects.