1/*
2
3PrintJobReader
4
5Copyright (c) 2002 Haiku.
6
7Author:
8	Michael Pfeiffer
9
10Permission is hereby granted, free of charge, to any person obtaining a copy of
11this software and associated documentation files (the "Software"), to deal in
12the Software without restriction, including without limitation the rights to
13use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
14of the Software, and to permit persons to whom the Software is furnished to do
15so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26THE SOFTWARE.
27
28*/
29
30#include "PrintJobReader.h"
31
32
33#include <stdio.h>
34
35
36#include <Picture.h>
37#include <PrintJob.h>
38
39
40// #pragma mark --- PrintJobPage
41
42
43PrintJobPage::PrintJobPage()
44	: fNextPicture(-1)
45	, fNumberOfPictures(0)
46	, fPicture(0)
47	, fStatus(B_ERROR)
48{
49}
50
51
52PrintJobPage::PrintJobPage(const PrintJobPage& copy)
53	: fJobFile(copy.fJobFile)
54	, fNextPicture(copy.fNextPicture)
55	, fNumberOfPictures(copy.fNumberOfPictures)
56	, fPicture(copy.fPicture)
57	, fStatus(copy.fStatus)
58{
59}
60
61
62PrintJobPage& PrintJobPage::operator=(const PrintJobPage& copy)
63{
64	if (this != &copy) {
65		fJobFile = copy.fJobFile;
66		fNextPicture = copy.fNextPicture;
67		fNumberOfPictures = copy.fNumberOfPictures;
68		fPicture = copy.fPicture;
69		fStatus = copy.fStatus;
70	}
71	return *this;
72}
73
74
75PrintJobPage::PrintJobPage(BFile* jobFile, off_t start)
76	: fJobFile(*jobFile)
77	, fPicture(0)
78	, fStatus(B_ERROR)
79{
80	off_t size;
81	if (fJobFile.GetSize(&size) != B_OK || start > size)
82		return;
83
84	if (fJobFile.Seek(start, SEEK_SET) != start)
85		return;
86
87	if (fJobFile.Read(&fNumberOfPictures, sizeof(int32)) == sizeof(int32)) {
88		// (sizeof(int32) * 10) == padding in _page_header_
89		fJobFile.Seek(sizeof(off_t) + sizeof(int32) * 10, SEEK_CUR);
90		fNextPicture = fJobFile.Position();
91		fStatus = B_OK;
92	}
93}
94
95
96status_t PrintJobPage::InitCheck() const
97{
98	return fStatus;
99}
100
101
102status_t PrintJobPage::NextPicture(BPicture& picture, BPoint& point, BRect& rect)
103{
104	if (fPicture >= fNumberOfPictures)
105		return B_ERROR;
106	fPicture++;
107
108	fJobFile.Seek(fNextPicture, SEEK_SET);
109	fJobFile.Read(&point, sizeof(BPoint));
110	fJobFile.Read(&rect, sizeof(BRect));
111	status_t rc = picture.Unflatten(&fJobFile);
112	fNextPicture = fJobFile.Position();
113
114	if (rc != B_OK)
115		fPicture = fNumberOfPictures;
116
117	return rc;
118}
119
120
121// # pragma mark --- PrintJobReader
122
123
124PrintJobReader::PrintJobReader(BFile* jobFile)
125	: fJobFile(*jobFile)
126	, fNumberOfPages(-1)
127	, fPageIndex(NULL)
128{
129	print_file_header header;
130	fJobFile.Seek(0, SEEK_SET);
131	if (fJobFile.Read(&header, sizeof(header)) == sizeof(header)) {
132		if (fJobSettings.Unflatten(&fJobFile) == B_OK) {
133			fNumberOfPages = header.page_count;
134			fPageIndex = new off_t[fNumberOfPages];
135
136			_BuildPageIndex();
137		}
138	}
139}
140
141
142PrintJobReader::~PrintJobReader()
143{
144	delete[] fPageIndex;
145}
146
147
148status_t PrintJobReader::InitCheck() const
149{
150	return fNumberOfPages > 0 ? B_OK : B_ERROR;
151}
152
153
154void PrintJobReader::_BuildPageIndex()
155{
156	off_t next_page;
157	int32 number_of_pictures;
158	for (int32 page = 0; page < fNumberOfPages; ++page) {
159		fPageIndex[page] = fJobFile.Position();
160		if (fJobFile.Read(&number_of_pictures, sizeof(int32)) == sizeof(int32)
161			&& fJobFile.Read(&next_page, sizeof(off_t)) == sizeof(off_t)
162			&& fPageIndex[page] < next_page) {
163			fJobFile.Seek(next_page, SEEK_SET);
164		} else {
165			fNumberOfPages = 0;
166			delete[] fPageIndex;
167			fPageIndex = NULL;
168			return;
169		}
170	}
171}
172
173
174status_t PrintJobReader::GetPage(int32 page, PrintJobPage& pjp)
175{
176	if (0 <= page && page < fNumberOfPages) {
177		PrintJobPage p(&fJobFile, fPageIndex[page]);
178		if (p.InitCheck() == B_OK) {
179			pjp = p;
180			return B_OK;
181		}
182	}
183	return B_ERROR;
184}
185
186
187int32 PrintJobReader::FirstPage() const
188{
189	int32 firstPage = -1;
190	fJobSettings.FindInt32("first_page", &firstPage);
191	return firstPage;
192}
193
194
195int32 PrintJobReader::LastPage() const
196{
197	int32 lastPage = -1;
198	fJobSettings.FindInt32("last_page", &lastPage);
199	return lastPage;
200}
201
202
203BRect PrintJobReader::PaperRect() const
204{
205	BRect r;
206	fJobSettings.FindRect("paper_rect", &r);
207	return r;
208}
209
210
211BRect PrintJobReader::PrintableRect() const
212{
213	BRect r;
214	fJobSettings.FindRect("printable_rect", &r);
215	return r;
216}
217
218
219void PrintJobReader::GetResolution(int32 *xdpi, int32 *ydpi) const
220{
221	fJobSettings.FindInt32("xres", xdpi);
222	fJobSettings.FindInt32("yres", ydpi);
223}
224
225
226float PrintJobReader::GetScale() const
227{
228	float scale = 1.0;
229	fJobSettings.FindFloat("scale", &scale);
230	return scale;
231}
232