Aurelon Open API 8.1.1
Loading...
Searching...
No Matches
AOI_Document.cpp
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"
9#include "../GLayer.h"
10#include "../GVector.h"
11#include "../GGroup.h"
12#include "../GPlaceHolder.h"
13#include <ACPL/Multithreading.h>
14#include "../GText.h"
15
16using namespace aur;
17using namespace aur::PDF;
18using namespace aur::ACPL;
19
26static bool FillObjectDetails( Object* object, PDF::Point mouse, bool stroke, Document* doc, AOI_Color* outHitColor )
27{
28 if( !object )
29 return false;
30
31 if( object->GetType() == gGroupType )
32 {
33 Group* grp = dynamic_cast<GroupPtr>(object);
34 Object* child;
35 child = grp->GetFirstChild();
36 int index = 0;
37 bool ret = false;
38 while( child && !ret )
39 {
40 ret = FillObjectDetails( child, mouse, stroke, doc, outHitColor );
41 child = grp->GetNthChild( ++index );
42 }
43 return ret;
44 }
45 if(object->GetType() == gPlaceHolderType)
46 {
47 SymbolPtr sym = dynamic_cast<SymbolPtr>( object );
48 if( sym && sym->GetObject() )
49 {
50 return FillObjectDetails( sym->GetObject() ,mouse ,stroke, doc, outHitColor );
51 }
52 }
53 StylePtr style = NULL;
54 ColorSpaceObject* space = NULL;
55 VectorPtr vector = dynamic_cast<VectorPtr>(object);
56 if( vector )
57 style = ( stroke && vector->GetStrokeStyle() ) ? vector->GetStrokeStyle() : vector->GetFillStyle();
58 else
59 {
60 SymbolPtr symbol = dynamic_cast<SymbolPtr>(object);
61 if( symbol )
62 style = (StylePtr)symbol->GetColor();
63 else
64 {
65 RasterPtr raster = dynamic_cast<RasterPtr>(object);
66 if ( raster )
67 {
68 Color color;
69 BitmapPtr bitmap = raster->GetBitmap();
70 Mapping invertMap = raster->mapping();
71 invertMap.Invert();
72 mouse.Map(invertMap);
73
74 space = raster->GetColorSpace();
75 bitmap->Open(NULL);
76 bitmap->GetPixel(int32_t(mouse.x), int32_t(mouse.y), color);
77 bitmap->Close();
78
79 outHitColor->space = AOI_ColorSpacePtr( color.space );
80 ::memcpy( outHitColor->channel, color.channel, space->NrOfComponents() * sizeof( uint16_t ) );
81 }
82 }
83 }
84
85 if (style)
86 {
87 switch(style->GetType())
88 {
89 case PDF::Style::eSolid:
90 {
91 SolidPtr color = dynamic_cast<SolidPtr>(style);
92 Color c;
93 color->GetColor(c);
94 space = color->GetSpace();
95 outHitColor->space = AOI_ColorSpacePtr( space );
96 ::memcpy( outHitColor->channel, c.channel, outHitColor->space->NrOfComponents() * sizeof( uint16_t ) );
97 }
98 break;
99 case PDF::Style::ePattern:
100 break;
101 case PDF::Style::eShading:
102 {
103 ShadingSpacePtr shade = dynamic_cast<ShadingSpacePtr>( style );
104 space = shade->GetColorSpace();
105 Color col;
106 if( shade->GetColor( mouse.x, mouse.y, col ) == false )
107 {
108 ClearStruct( col );
109 col.space = space;
110 }
111 outHitColor->space = AOI_ColorSpacePtr( col.space );
112 ::memcpy( outHitColor->channel, col.channel, space->NrOfComponents() * sizeof( uint16_t ) );
113 break;
114 }
115 }
116 }
117
118 if( space )
119 {
120 if( space->ResourceType() == IndexColorSpace::eResourceType )
121 {
122 IndexColorSpace* indexed = dynamic_cast<IndexColorSpace*>( space );
123 Color c;
124 c.space = indexed->GetBase();
125 indexed->GetColor( outHitColor->channel[0] >> 8, c.channel );
126 space = c.space;
127 outHitColor->space = AOI_ColorSpacePtr( c.space );
128 ::memcpy( outHitColor->channel, c.channel, space->NrOfComponents() * sizeof( uint16_t ) );
129 }
130 }
131 return space != NULL;
132}
133
134
143 mDocument( NULL ),
144 mInstance( NULL ),
145 mSpotColorList( NULL ),
146 mUseSimpleRenderer( false ),
147 mPDFSpec( NULL ),
148 mImageSpec( NULL )
149{
150 if( instance )
151 mInstance = instance->mInstance;
152}
153
154::ExceptionCode AOI_Document::ConvertPStoPDF( const FileSpec& pathToPS, const FileSpec& pathToPDF )
155{
156 static CriticalSection sPSAccess;
157 sPSAccess.Enter();
158
159 ::ExceptionCode err = NoError;
160
161 try
162 {
163 pathToPDF.Create();
164
165 String psError;
166 String psFonts;
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 );
172 }
173 catch( aur::ExceptionCode psErr )
174 {
175 err = psErr;
176 pathToPDF.Delete();
177 }
178 catch( ... )
179 {
180 err = ErrFatal;
181 pathToPDF.Delete();
182 }
183
184 sPSAccess.Leave();
185 return err;
186}
187
196void AOI_Document::Open( const aur::ACPL::FileSpec& path, const char* ownerPassword, const char* userPassword )
197{
198 delete mImageSpec;
199 mImageSpec = NULL;
200 delete mPDFSpec;
201 mPDFSpec = NULL;
202
203 mDocument = new Document( NULL, mInstance );
204 try
205 {
206 FileStream stream( path, eReadPermission );
207 if( stream.GetLength() == 0 )
208 {
209 mDocument->GetInstance()->Error( 1, 1, "File is 0 bytes long" );
210 return;
211 }
212 }
213 catch(...)
214 {
215 mDocument->GetInstance()->Error( 1, 2, "Error while opening file" );
216 return;
217 }
218 String fileType;
219 Document::DetermineFileType( path, fileType );
220 if( mUseSimpleRenderer && ( fileType == "tif" || fileType == "jpg" ) )
221 {
222 Document::Info info;
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, "+" ) )
229 {
230 mImageSpec = new FileSpec( path );
231 mDocument->GetPage()->SetDimensions( info.pages->front() );
232 return;
233 }
234 }
235 mUseSimpleRenderer = false;
236
237 if( fileType == "eps" )
238 {
239 mPDFSpec = new FileSpec();
240 mPDFSpec->CreateTemporary( NULL, "pdf" );
241
242 aur::ExceptionCode psErr = ConvertPStoPDF( path, *mPDFSpec );
243 if( psErr == NoError )
244 mDocument->OpenFile( *mPDFSpec, ownerPassword, userPassword );
245 else
246 mDocument->GetInstance()->Error( 100, uint16_t(psErr), "PostScript Error" );
247 }
248 else
249 {
250 try
251 {
252 mDocument->OpenFile( path, ownerPassword, userPassword );
253 }
254 catch( aur::ExceptionCode plugErr )
255 {
256 if( plugErr == ErrUserCanceled )
257 mDocument->GetInstance()->Error( 100, ErrUserCanceled, "Plugin User Canceled" );
258 else
259 mDocument->GetInstance()->Error( 100, uint16_t(plugErr), "Plugin Error" );
260 }
261 catch( ... )
262 {
263 mDocument->GetInstance()->Error( 100, 1, "Plugin fatal error" );
264 }
265 }
266}
267
268void AOI_Document::Open( const char16_t* path )
269{
270 Open( FileSpec( path ) );
271}
272
273AOI_Document::~AOI_Document()
274{
275 delete mDocument;
276 if( mPDFSpec )
277 mPDFSpec->Delete();
278 delete mPDFSpec;
279 delete mImageSpec;
280 delete[] mSpotColorList;
281}
282
290{
291 return mDocument->GetPageCount();
292}
293
304AOI_PagePtr AOI_Document::GetPage( uint32_t pageNr ) const
305{
306 mDocument->SetCurrentPage( pageNr );
307 return AOI_PagePtr( mDocument->GetPage( pageNr ) );
308}
309
322{
323 ObjectPtr o = ObjectPtr( object );
324 bool res = mDocument->TraverseNext( o );
325 object = (AOI_Object*)o;
326 return res;
327}
328
337AOI_ColorSpacePtr AOI_Document::GetDocumentColorSpace() const
338{
339 return AOI_ColorSpacePtr( mDocument->GetDocumentColorSpace() );
340}
341
350AOI_ColorSpacePtr AOI_Document::GetLabColorSpace() const
351{
352 return AOI_ColorSpacePtr( mDocument->GetLabColorSpace() );
353}
354
364{
365 return AOI_ColorSpacePtr( mDocument->GetDeviceGrayColorSpace() );
366}
367
377{
378 return AOI_ColorSpacePtr( mDocument->GetDeviceRGBColorSpace() );
379}
380
390{
391 return AOI_ColorSpacePtr( mDocument->GetDeviceCMYKColorSpace() );
392}
393
394static bool StyleIsBW( StylePtr style )
395{
396 bool isBW = true;
397 SolidPtr color = dynamic_cast<SolidPtr>(style);
398 if( color && ( color->GetSpace()->Space() & GraySpace ) != GraySpace )
399 {
400 //allow non gray spaces if color is black and white based
401 Color col;
402 color->GetColor( col );
403 if( ( col.space->Space() & DeviceNSpace ) == DeviceNSpace || ( col.space->Space() & CMYKSpace ) == CMYKSpace )
404 {
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 )
409 isBW = false;
410 }
411 else if( ( col.space->Space() & RGBSpace ) == RGBSpace )
412 {
413 if ( ! ( ( col.channel[0] == col.channel[1] ) && ( col.channel[1] == col.channel[2] ) ) )
414 isBW = false;
415 }
416 else
417 isBW = false;
418 }
419 return isBW;
420}
421
422static void ParseLayer( ObjectPtr obj, PagePtr page, bool& isBW )
423{
424 if( !obj )
425 return;
426
427 VectorPtr vector = NULL;
428 do
429 {
430 if( ( vector = dynamic_cast<VectorPtr>(obj) ) )
431 {
432 isBW = ( StyleIsBW( vector->GetFillStyle() ) && StyleIsBW( vector->GetStrokeStyle() ) );
433 obj = obj->GetNext();
434 }
435 else if( obj->GetType() == gGroupType )
436 {
437 ParseLayer( ((GroupPtr)obj)->GetFirstChild(), page, isBW );
438 obj = obj->GetNext();
439 }
440 else if( obj->GetType() == gPlaceHolderType || obj->GetType() == gSymbolType )
441 {
442 ObjectPtr child = NULL;
443 if( obj->GetType() == gPlaceHolderType )
444 child = ((PlaceHolderPtr)obj)->GetObject();
445 else
446 child = ((SymbolPtr)obj)->GetObject();
447 if( child )
448 ParseLayer( child, page, isBW );
449 obj = obj->GetNext();
450 }
451 else
452 obj = obj->GetNext();
453 }
454 while( obj && isBW );
455}
456
465{
466 bool isBW = true;
467 for( uint32_t i = 0 ; i < GetPageCount() && isBW ; i++ )
468 {
469 PagePtr page = mDocument->GetPage( i );
470 for( LayerPtr layer = page->GetFirstLayer() ; layer && isBW; layer = (LayerPtr)layer->GetNext() )
471 {
472 ObjectPtr obj = layer->GetFirstChild();
473 ParseLayer( obj, page, isBW );
474 }
475 }
476 return isBW;
477}
478
479bool static CheckFonts( const std::vector<FontFile*>& allFonts, ObjectPtr obj )
480{
481 PDF::TextPtr textObject = dynamic_cast<PDF::TextPtr>( obj );
482 if( textObject && textObject->Visible() )
483 {
484 PropsT props;
485 textObject->GetProperties( props );
486 for( auto& nFont : allFonts )
487 if( ::stricmp( props.style.fontName, nFont->GetName() ) == 0 )
488 return true;
489 }
490 else
491 {
492 GroupPtr group = dynamic_cast<GroupPtr>( obj );
493 if( group )
494 {
495 for( ObjectPtr child = group->GetFirstChild(); child; child = child->GetNext() )
496 if( CheckFonts( allFonts, child ) )
497 return true;
498 }
499 }
500 return false;
501}
502
508bool AOI_Document::FontExists( bool onlyUsed ) const
509{
510 bool fontExists = false;
511 uint32_t indexPage;
512 uint32_t currentPage = mDocument->GetCurrentPage();
513
514 std::vector<FontFile*> allEmbededFonts;
515
516 indexPage = currentPage;
517 for( uint32_t i = 0; i < mDocument->GetPageCount(); ++i )
518 {
519 if( indexPage >= mDocument->GetPageCount() )
520 indexPage = 0;
521 mDocument->SetCurrentPage( indexPage );
522 allEmbededFonts = mDocument->FontUsage();
523 fontExists = !allEmbededFonts.empty();
524 if( fontExists && !onlyUsed )
525 break;
526 }
527 mDocument->SetCurrentPage( currentPage );
528 if( fontExists && onlyUsed )
529 {
530 fontExists = false;
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 ) )
535 {
536 fontExists = true;
537 break;
538 }
539 }
540 return fontExists;
541}
542
553::ExceptionCode AOI_Document::SaveAsPDF( const FileSpec& path )
554{
555 try
556 {
557 mDocument->SavePDF( path, false, path.FileTitle() );
558 }
559 catch( aur::ExceptionCode err )
560 {
561 return err;
562 }
563 return NoError;
564}
565
578{
579 delete[] mSpotColorList;
580 mSpotColorList = NULL;
581
582 std::vector<SpotColorName> list;
583 DeviceN* devn = NULL;
584 uint32_t i,j;
585 while( ( devn = (DeviceN*)mDocument->TraverseCommitedResources( DeviceN::eResourceType, devn ) ) != NULL )
586 {
587 for( j = 0; j != devn->NrOfComponents(); ++j )
588 {
589 SpotColorName n = devn->ChannelName( j );
590 bool found = ::strcmp( n, "None" ) == 0 || ::strcmp( n, "All" ) == 0;
591 // Find channel in document colorants
592 if( !found )
593 {
594 for( i = 0; i != list.size() && ::stricmp( n, list[i] ); ++i )
595 ;
596 if( i == list.size() )
597 list.push_back( n );
598 }
599 }
600 }
601
602 if( list.size() )
603 {
604 mSpotColorList = new SpotColorName[ list.size() + 1 ];
605 for( i = 0; i != list.size(); ++i )
606 mSpotColorList[i] = list[i];
607 mSpotColorList[i] = NULL;
608 }
609
610 return mSpotColorList;
611}
612
631AOI_Object* AOI_Document::HitTest( AOI_Point p, int16_t snapDistance, bool& stroke, AOI_Color* outHitColor )
632{
633 PDF::Point fp;
634 fp.x = p.x;
635 fp.y = p.y;
636 HitWhatT what;
637 what.u.all = 0;
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 )
646 {
647 PDF::Point mouse;
648 mouse.x = p.x;
649 mouse.y = p.y;
650 FillObjectDetails( hitObject, mouse, stroke, mDocument, outHitColor );
651 }
652 return AOI_ObjectPtr( hitObject );
653}
654
655void AOI_Document::SimpleImage()
656{
657 mUseSimpleRenderer = true;
658}
659
663void AOI_Document::CloseFile( bool keepVM, bool createDefaults )
664{
665 mDocument->CloseFile( keepVM, createDefaults );
666}
667
668AOI_DocumentInfo::AOI_DocumentInfo() :
669 fileSize( 0 ),
670 pageCount( 0 ),
671 width( 0 ),
672 height( 0 ),
673 space( AOI_NoSpace ),
674 encrypted( false ),
675 denyPrint( false ),
676 denyChange( false ),
677 denyCopy( false ),
678 denyNotes( false ),
679 orientation( 0 ),
680 xResolution( 0 ),
681 yResolution( 0 ),
682 pixelWidth( 0 ),
683 pixelHeight( 0 ),
684 resolutionUnit( 0 ),
685 exposureTime( 0 ),
686 Fnumber( 0 ),
687 ISOSpeedRating( 0 ),
688 exposureBiasValue( 0 )
689{
690}
691
692bool AOI_DocumentInfo::GetInfo( const FileSpec& path )
693{
694 try
695 {
696 aur::PDF::Document::Info info;
697 PDF::Document::GetInfo( path, info );
698
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;
709 if( info.fonts )
710 fonts = *info.fonts;
711 fileType = info.fileType;
712 description = info.description ? info.description : "";
713 artist = info.artist; // name of the camera owner
714 software = info.software; // Exif software version
715 make = info.make;
716 model = info.model;
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;
729 }
730 catch(...)
731 {
732 }
733 return false;
734}
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.
Definition AOI_Object.h:13
Page in the document.
Definition AOI_Page.h:11
Coordinate.
Definition AOI_Types.h:137