1 //------------------------------------------------------------------------------
2 // emPsRenderer.h
3 //
4 // Copyright (C) 2006-2009,2014,2018 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emPsRenderer_h
22 #define emPsRenderer_h
23 
24 #ifndef emTimer_h
25 #include <emCore/emTimer.h>
26 #endif
27 
28 #ifndef emProcess_h
29 #include <emCore/emProcess.h>
30 #endif
31 
32 #ifndef emPriSchedAgent_h
33 #include <emCore/emPriSchedAgent.h>
34 #endif
35 
36 #ifndef emImage_h
37 #include <emCore/emImage.h>
38 #endif
39 
40 #ifndef emPsDocument_h
41 #include <emPs/emPsDocument.h>
42 #endif
43 
44 
45 class emPsRenderer : public emModel {
46 
47 public:
48 
49 	static emRef<emPsRenderer> Acquire(emRootContext & rootContext);
50 
51 	typedef void * JobHandle;
52 
53 	JobHandle StartJob(
54 		const emPsDocument & document, int pageIndex,
55 		emImage & outputImage, double priority=0.0,
56 		emEngine * listenEngine=NULL
57 	);
58 
59 	void SetJobPriority(JobHandle jobHandle, double priority);
60 
61 	void SetJobListenEngine(JobHandle jobHandle, emEngine * listenEngine);
62 
63 	enum JobState {
64 		JS_WAITING,
65 		JS_RUNNING,
66 		JS_ERROR,
67 		JS_SUCCESS
68 	};
69 	JobState GetJobState(JobHandle jobHandle) const;
70 
71 	const emString & GetJobErrorText(JobHandle jobHandle) const;
72 
73 	void CloseJob(JobHandle jobHandle);
74 
75 protected:
76 
77 	emPsRenderer(emContext & context, const emString & name);
78 	virtual ~emPsRenderer();
79 
80 	virtual bool Cycle();
81 
82 private:
83 
84 	struct Job {
85 		emPsDocument Document;
86 		int PageIndex;
87 		emImage * Image;
88 		double Priority;
89 		emEngine * ListenEngine;
90 		JobState State;
91 		emString ErrorText;
92 		Job * Prev;
93 		Job * Next;
94 	};
95 
96 	enum MainStateType {
97 		COLD_WAIT_JOB,
98 		COLD_WAIT_ACCESS,
99 		PREPARE_PROCESS,
100 		RUN_JOB,
101 		HOT_WAIT_JOB,
102 		HOT_WAIT_ACCESS,
103 		QUIT_PROCESS
104 	};
105 
106 	void AddToJobList(Job * job);
107 	void RemoveFromJobList(Job * job);
108 
109 	Job * SearchBestJob();
110 	Job * SearchBestSameDocJob();
111 
112 	void SetJobState(Job * job, JobState state, emString errorText="");
113 	void FailCurrentJob(emString errorMessage);
114 	void FailDocJobs(emString errorMessage);
115 	void FailAllJobs(emString errorMessage);
116 
117 	void UpdatePSPriority();
118 
119 	void TryStartProcess();
120 
121 	void PrepareWritingStartup();
122 	void PrepareWritingPage();
123 	bool TryWrite();
124 	bool IsWritingFinished() const;
125 
126 	void PrepareReadingStartup();
127 	void PrepareReadingPage();
128 	bool TryRead();
129 	int ParseImageHeader(const char * buf, int len);
130 	static int ParseImageDecimal(const char * buf, int len, int * pNumber);
131 	int ParseImageData(const char * buf, int len);
132 	bool IsReadingFinished() const;
133 
134 	class PSAgentClass : public emPriSchedAgent {
135 	public:
136 		PSAgentClass(emPsRenderer & interpreter);
137 	protected:
138 		virtual void GotAccess();
139 	private:
140 		emPsRenderer & Renderer;
141 	};
142 	friend class PSAgentClass;
143 
144 	emProcess Process;
145 	emTimer Timer;
146 
147 	PSAgentClass PSAgent;
148 	bool PSPriorityValid;
149 
150 	Job * FirstJob;
151 	Job * LastJob;
152 
153 	MainStateType MainState;
154 
155 	Job * CurrentJob;
156 	emPsDocument CurrentDocument;
157 	int CurrentPageIndex;
158 
159 	enum WriterStateType {
160 		WRITING_STARTUP,
161 		WRITING_PAGE_SIZE,
162 		WRITING_PAGE,
163 		WRITING_SYNC,
164 		WRITING_FINISHED
165 	};
166 	WriterStateType WriterState;
167 	emString WriteCommand;
168 	int WriterPos;
169 
170 	enum ReaderStateType {
171 		READING_IMAGE_HEADER,
172 		READING_IMAGE_DATA,
173 		READING_SYNC,
174 		READING_FINISHED
175 	};
176 	ReaderStateType ReaderState;
177 	char ReadBuffer[131072];
178 	int ReadBufferFill;
179 	int RdSyncSearchPos;
180 	int RdImgFormat,RdImgW,RdImgH,RdImgMaxVal,RdImgX,RdImgY;
181 	bool RdImgDone;
182 
183 	static const char * const SyncString;
184 };
185 
SetJobListenEngine(JobHandle jobHandle,emEngine * listenEngine)186 inline void emPsRenderer::SetJobListenEngine(
187 	JobHandle jobHandle, emEngine * listenEngine
188 )
189 {
190 	((Job*)jobHandle)->ListenEngine=listenEngine;
191 }
192 
GetJobState(JobHandle jobHandle)193 inline emPsRenderer::JobState emPsRenderer::GetJobState(
194 	JobHandle jobHandle
195 ) const
196 {
197 	return ((Job*)jobHandle)->State;
198 }
199 
GetJobErrorText(JobHandle jobHandle)200 inline const emString & emPsRenderer::GetJobErrorText(
201 	JobHandle jobHandle
202 ) const
203 {
204 	return ((Job*)jobHandle)->ErrorText;
205 }
206 
IsWritingFinished()207 inline bool emPsRenderer::IsWritingFinished() const
208 {
209 	return WriterState==WRITING_FINISHED;
210 }
211 
IsReadingFinished()212 inline bool emPsRenderer::IsReadingFinished() const
213 {
214 	return ReaderState==READING_FINISHED;
215 }
216 
217 
218 #endif
219