xref: /haiku/src/kits/interface/PictureDataWriter.cpp (revision b1af0a7a247358c80de46e5400f572d2f00fca3a)
17022e790SStefano Ceccherini /*
27022e790SStefano Ceccherini  * Copyright 2006, Haiku Inc.
37022e790SStefano Ceccherini  * Distributed under the terms of the MIT License.
47022e790SStefano Ceccherini  *
57022e790SStefano Ceccherini  * Authors:
67022e790SStefano Ceccherini  *		Stefano Ceccherini (burton666@libero.it)
77022e790SStefano Ceccherini  */
87022e790SStefano Ceccherini 
96f867cc1SStephan Aßmus #include <PictureDataWriter.h>
106f867cc1SStephan Aßmus 
116f867cc1SStephan Aßmus #include <stdio.h>
126f867cc1SStephan Aßmus 
13420fe80eSStefano Ceccherini #include <DataIO.h>
14420fe80eSStefano Ceccherini #include <Point.h>
15420fe80eSStefano Ceccherini #include <Rect.h>
16253d42a6SStefano Ceccherini #include <Region.h>
17420fe80eSStefano Ceccherini 
18420fe80eSStefano Ceccherini #include <PictureProtocol.h>
19420fe80eSStefano Ceccherini 
2084c2abeeSStefano Ceccherini #define THROW_ERROR(error) throw (status_t)(error)
2184c2abeeSStefano Ceccherini 
22feb557a6SStefano Ceccherini // TODO: Review writing of strings. AFAIK in the picture data format
23feb557a6SStefano Ceccherini // They are not supposed to be NULL terminated (at least, it's not mandatory)
24feb557a6SStefano Ceccherini // and we should write their size.
254bfa8f22SStefano Ceccherini PictureDataWriter::PictureDataWriter()
264bfa8f22SStefano Ceccherini 	:
274bfa8f22SStefano Ceccherini 	fData(NULL)
284bfa8f22SStefano Ceccherini {
294bfa8f22SStefano Ceccherini }
304bfa8f22SStefano Ceccherini 
314bfa8f22SStefano Ceccherini 
32420fe80eSStefano Ceccherini PictureDataWriter::PictureDataWriter(BPositionIO *data)
33420fe80eSStefano Ceccherini 	:
34420fe80eSStefano Ceccherini 	fData(data)
35420fe80eSStefano Ceccherini {
36420fe80eSStefano Ceccherini }
37420fe80eSStefano Ceccherini 
38420fe80eSStefano Ceccherini 
39420fe80eSStefano Ceccherini status_t
404bfa8f22SStefano Ceccherini PictureDataWriter::SetTo(BPositionIO *data)
414bfa8f22SStefano Ceccherini {
42140334f8SStefano Ceccherini 	if (data == NULL)
43140334f8SStefano Ceccherini 		return B_BAD_VALUE;
444bfa8f22SStefano Ceccherini 	fData = data;
454bfa8f22SStefano Ceccherini 	return B_OK;
464bfa8f22SStefano Ceccherini }
474bfa8f22SStefano Ceccherini 
484bfa8f22SStefano Ceccherini 
494bfa8f22SStefano Ceccherini status_t
50420fe80eSStefano Ceccherini PictureDataWriter::WriteSetOrigin(const BPoint &point)
51420fe80eSStefano Ceccherini {
52140334f8SStefano Ceccherini 	try {
53420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_ORIGIN);
54420fe80eSStefano Ceccherini 		Write<BPoint>(point);
55420fe80eSStefano Ceccherini 		EndOp();
56140334f8SStefano Ceccherini 	} catch (status_t &status) {
57140334f8SStefano Ceccherini 		return status;
58140334f8SStefano Ceccherini 	}
59420fe80eSStefano Ceccherini 	return B_OK;
60420fe80eSStefano Ceccherini }
61420fe80eSStefano Ceccherini 
62420fe80eSStefano Ceccherini 
63420fe80eSStefano Ceccherini status_t
64420fe80eSStefano Ceccherini PictureDataWriter::WriteInvertRect(const BRect &rect)
65420fe80eSStefano Ceccherini {
66140334f8SStefano Ceccherini 	try {
67420fe80eSStefano Ceccherini 		WriteSetDrawingMode(B_OP_INVERT);
68420fe80eSStefano Ceccherini 
69420fe80eSStefano Ceccherini 		BeginOp(B_PIC_FILL_RECT);
70420fe80eSStefano Ceccherini 		Write<BRect>(rect);
71420fe80eSStefano Ceccherini 		EndOp();
72420fe80eSStefano Ceccherini 
73420fe80eSStefano Ceccherini 		WriteSetDrawingMode(B_OP_COPY);
74140334f8SStefano Ceccherini 	} catch (status_t &status) {
75140334f8SStefano Ceccherini 		return status;
76140334f8SStefano Ceccherini 	}
77420fe80eSStefano Ceccherini 	return B_OK;
78420fe80eSStefano Ceccherini }
79420fe80eSStefano Ceccherini 
80420fe80eSStefano Ceccherini 
81420fe80eSStefano Ceccherini status_t
82420fe80eSStefano Ceccherini PictureDataWriter::WriteSetDrawingMode(const drawing_mode &mode)
83420fe80eSStefano Ceccherini {
84140334f8SStefano Ceccherini 	try {
85420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_DRAWING_MODE);
86420fe80eSStefano Ceccherini 		Write<int16>((int16)mode);
87420fe80eSStefano Ceccherini 		EndOp();
88140334f8SStefano Ceccherini 	} catch (status_t &status) {
89140334f8SStefano Ceccherini 		return status;
90140334f8SStefano Ceccherini 	}
91420fe80eSStefano Ceccherini 	return B_OK;
92420fe80eSStefano Ceccherini }
93420fe80eSStefano Ceccherini 
94420fe80eSStefano Ceccherini 
95420fe80eSStefano Ceccherini status_t
96690c7474SStefano Ceccherini PictureDataWriter::WriteSetPenLocation(const BPoint &point)
97690c7474SStefano Ceccherini {
98690c7474SStefano Ceccherini 	try {
99690c7474SStefano Ceccherini 		BeginOp(B_PIC_SET_PEN_LOCATION);
100690c7474SStefano Ceccherini 		Write<BPoint>(point);
101690c7474SStefano Ceccherini 		EndOp();
102690c7474SStefano Ceccherini 	} catch (status_t &status) {
103690c7474SStefano Ceccherini 		return status;
104690c7474SStefano Ceccherini 	}
105690c7474SStefano Ceccherini 	return B_OK;
106690c7474SStefano Ceccherini }
107690c7474SStefano Ceccherini 
108690c7474SStefano Ceccherini 
109690c7474SStefano Ceccherini status_t
110420fe80eSStefano Ceccherini PictureDataWriter::WriteSetPenSize(const float &penSize)
111420fe80eSStefano Ceccherini {
112140334f8SStefano Ceccherini 	try {
113420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_PEN_SIZE);
114420fe80eSStefano Ceccherini 		Write<float>(penSize);
115420fe80eSStefano Ceccherini 		EndOp();
116140334f8SStefano Ceccherini 	} catch (status_t &status) {
117140334f8SStefano Ceccherini 		return status;
118140334f8SStefano Ceccherini 	}
119420fe80eSStefano Ceccherini 	return B_OK;
120420fe80eSStefano Ceccherini }
121420fe80eSStefano Ceccherini 
122420fe80eSStefano Ceccherini 
123420fe80eSStefano Ceccherini status_t
124420fe80eSStefano Ceccherini PictureDataWriter::WriteSetLineMode(const cap_mode &cap, const join_mode &join, const float &miterLimit)
125420fe80eSStefano Ceccherini {
126140334f8SStefano Ceccherini 	try {
127420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_LINE_MODE);
128420fe80eSStefano Ceccherini 		Write<int16>((int16)cap);
129420fe80eSStefano Ceccherini 		Write<int16>((int16)join);
130420fe80eSStefano Ceccherini 		Write<float>(miterLimit);
131420fe80eSStefano Ceccherini 		EndOp();
132140334f8SStefano Ceccherini 	} catch (status_t &status) {
133140334f8SStefano Ceccherini 		return status;
134140334f8SStefano Ceccherini 	}
135420fe80eSStefano Ceccherini 	return B_OK;
136420fe80eSStefano Ceccherini }
137420fe80eSStefano Ceccherini 
138420fe80eSStefano Ceccherini 
139420fe80eSStefano Ceccherini status_t
140420fe80eSStefano Ceccherini PictureDataWriter::WriteSetScale(const float &scale)
141420fe80eSStefano Ceccherini {
142140334f8SStefano Ceccherini 	try {
143420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_SCALE);
144420fe80eSStefano Ceccherini 		Write<float>(scale);
145420fe80eSStefano Ceccherini 		EndOp();
146140334f8SStefano Ceccherini 	} catch (status_t &status) {
147140334f8SStefano Ceccherini 		return status;
148140334f8SStefano Ceccherini 	}
149420fe80eSStefano Ceccherini 	return B_OK;
150420fe80eSStefano Ceccherini }
151420fe80eSStefano Ceccherini 
152420fe80eSStefano Ceccherini 
153420fe80eSStefano Ceccherini status_t
15437033892SStefano Ceccherini PictureDataWriter::WriteSetPattern(const pattern &pat)
15537033892SStefano Ceccherini {
15637033892SStefano Ceccherini 	try {
15737033892SStefano Ceccherini 		BeginOp(B_PIC_SET_STIPLE_PATTERN);
15837033892SStefano Ceccherini 		Write<pattern>(pat);
15937033892SStefano Ceccherini 		EndOp();
16037033892SStefano Ceccherini 	} catch (status_t &status) {
16137033892SStefano Ceccherini 		return status;
16237033892SStefano Ceccherini 	}
16337033892SStefano Ceccherini 	return B_OK;
16437033892SStefano Ceccherini }
16537033892SStefano Ceccherini 
16637033892SStefano Ceccherini 
16737033892SStefano Ceccherini status_t
168253d42a6SStefano Ceccherini PictureDataWriter::WriteSetClipping(/*const */BRegion &region)
169253d42a6SStefano Ceccherini {
170253d42a6SStefano Ceccherini 	// TODO: I don't know if it's compatible with R5's BPicture version
171253d42a6SStefano Ceccherini 	try {
172253d42a6SStefano Ceccherini 		const int32 numRects = region.CountRects();
173253d42a6SStefano Ceccherini 		if (numRects > 0 && region.Frame().IsValid()) {
174253d42a6SStefano Ceccherini 			BeginOp(B_PIC_SET_CLIPPING_RECTS);
17546b4e489SStefano Ceccherini 			Write<uint32>(numRects);
17646b4e489SStefano Ceccherini 			for (int32 i = 0; i < numRects; i++) {
177253d42a6SStefano Ceccherini 				Write<BRect>(region.RectAt(i));
17846b4e489SStefano Ceccherini 			}
179253d42a6SStefano Ceccherini 			EndOp();
180253d42a6SStefano Ceccherini 		} else
181253d42a6SStefano Ceccherini 			WriteClearClipping();
182253d42a6SStefano Ceccherini 	} catch (status_t &status) {
183253d42a6SStefano Ceccherini 		return status;
184253d42a6SStefano Ceccherini 	}
18546b4e489SStefano Ceccherini 
186253d42a6SStefano Ceccherini 	return B_OK;
187253d42a6SStefano Ceccherini }
188253d42a6SStefano Ceccherini 
189253d42a6SStefano Ceccherini 
190253d42a6SStefano Ceccherini status_t
191253d42a6SStefano Ceccherini PictureDataWriter::WriteClearClipping()
192253d42a6SStefano Ceccherini {
193253d42a6SStefano Ceccherini 	try {
194253d42a6SStefano Ceccherini 		BeginOp(B_PIC_CLEAR_CLIPPING_RECTS);
195253d42a6SStefano Ceccherini 		EndOp();
196253d42a6SStefano Ceccherini 	} catch (status_t &status) {
197253d42a6SStefano Ceccherini 		return status;
198253d42a6SStefano Ceccherini 	}
199253d42a6SStefano Ceccherini 	return B_OK;
200253d42a6SStefano Ceccherini }
201253d42a6SStefano Ceccherini 
202253d42a6SStefano Ceccherini 
203253d42a6SStefano Ceccherini status_t
204420fe80eSStefano Ceccherini PictureDataWriter::WriteSetHighColor(const rgb_color &color)
205420fe80eSStefano Ceccherini {
206140334f8SStefano Ceccherini 	try {
207420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_FORE_COLOR);
208420fe80eSStefano Ceccherini 		Write<rgb_color>(color);
209420fe80eSStefano Ceccherini 		EndOp();
210140334f8SStefano Ceccherini 	} catch (status_t &status) {
211140334f8SStefano Ceccherini 		return status;
212140334f8SStefano Ceccherini 	}
213420fe80eSStefano Ceccherini 	return B_OK;
214420fe80eSStefano Ceccherini }
215420fe80eSStefano Ceccherini 
216420fe80eSStefano Ceccherini 
217420fe80eSStefano Ceccherini status_t
218420fe80eSStefano Ceccherini PictureDataWriter::WriteSetLowColor(const rgb_color &color)
219420fe80eSStefano Ceccherini {
220140334f8SStefano Ceccherini 	try {
221420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_BACK_COLOR);
222420fe80eSStefano Ceccherini 		Write<rgb_color>(color);
223420fe80eSStefano Ceccherini 		EndOp();
224140334f8SStefano Ceccherini 	} catch (status_t &status) {
225140334f8SStefano Ceccherini 		return status;
226140334f8SStefano Ceccherini 	}
227420fe80eSStefano Ceccherini 	return B_OK;
228420fe80eSStefano Ceccherini }
229420fe80eSStefano Ceccherini 
230420fe80eSStefano Ceccherini 
231420fe80eSStefano Ceccherini status_t
232420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawRect(const BRect &rect, const bool &fill)
233420fe80eSStefano Ceccherini {
234140334f8SStefano Ceccherini 	try {
235420fe80eSStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT);
236420fe80eSStefano Ceccherini 		Write<BRect>(rect);
237420fe80eSStefano Ceccherini 		EndOp();
238140334f8SStefano Ceccherini 	} catch (status_t &status) {
239140334f8SStefano Ceccherini 		return status;
240140334f8SStefano Ceccherini 	}
241420fe80eSStefano Ceccherini 	return B_OK;
242420fe80eSStefano Ceccherini }
243420fe80eSStefano Ceccherini 
244420fe80eSStefano Ceccherini 
245420fe80eSStefano Ceccherini status_t
246420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawRoundRect(const BRect &rect, const BPoint &radius, const bool &fill)
247420fe80eSStefano Ceccherini {
248140334f8SStefano Ceccherini 	try {
249420fe80eSStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT);
250420fe80eSStefano Ceccherini 		Write<BRect>(rect);
251420fe80eSStefano Ceccherini 		Write<BPoint>(radius);
252420fe80eSStefano Ceccherini 		EndOp();
253140334f8SStefano Ceccherini 	} catch (status_t &status) {
254140334f8SStefano Ceccherini 		return status;
255140334f8SStefano Ceccherini 	}
256420fe80eSStefano Ceccherini 	return B_OK;
257420fe80eSStefano Ceccherini }
258420fe80eSStefano Ceccherini 
259420fe80eSStefano Ceccherini 
260420fe80eSStefano Ceccherini status_t
261420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawEllipse(const BRect &rect, const bool &fill)
262420fe80eSStefano Ceccherini {
263140334f8SStefano Ceccherini 	try {
264420fe80eSStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE);
265420fe80eSStefano Ceccherini 		Write<BRect>(rect);
266420fe80eSStefano Ceccherini 		EndOp();
267140334f8SStefano Ceccherini 	} catch (status_t &status) {
268140334f8SStefano Ceccherini 		return status;
269140334f8SStefano Ceccherini 	}
270420fe80eSStefano Ceccherini 	return B_OK;
271420fe80eSStefano Ceccherini }
272420fe80eSStefano Ceccherini 
273420fe80eSStefano Ceccherini 
274420fe80eSStefano Ceccherini status_t
275420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawArc(const BPoint &center, const BPoint &radius,
276420fe80eSStefano Ceccherini 				const float &startTheta, const float &arcTheta, const bool &fill)
277420fe80eSStefano Ceccherini {
278140334f8SStefano Ceccherini 	try {
279420fe80eSStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC);
280420fe80eSStefano Ceccherini 		Write<BPoint>(center);
281420fe80eSStefano Ceccherini 		Write<BPoint>(radius);
282420fe80eSStefano Ceccherini 		Write<float>(startTheta);
283420fe80eSStefano Ceccherini 		Write<float>(arcTheta);
284420fe80eSStefano Ceccherini 		EndOp();
285140334f8SStefano Ceccherini 	} catch (status_t &status) {
286140334f8SStefano Ceccherini 		return status;
287140334f8SStefano Ceccherini 	}
288420fe80eSStefano Ceccherini 	return B_OK;
289420fe80eSStefano Ceccherini }
290420fe80eSStefano Ceccherini 
291420fe80eSStefano Ceccherini 
292420fe80eSStefano Ceccherini status_t
293ed5de868SStefano Ceccherini PictureDataWriter::WriteDrawPolygon(const int32 &numPoints, BPoint *points,
294ed5de868SStefano Ceccherini 				const bool &isClosed, const bool &fill)
295ed5de868SStefano Ceccherini {
296ed5de868SStefano Ceccherini 	try {
297ed5de868SStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_POLYGON : B_PIC_STROKE_POLYGON);
298ed5de868SStefano Ceccherini 		Write<int32>(numPoints);
299ed5de868SStefano Ceccherini 		for (int32 i = 0; i < numPoints; i++)
300ed5de868SStefano Ceccherini 			Write<BPoint>(points[i]);
301ed5de868SStefano Ceccherini 		if (!fill)
302ed5de868SStefano Ceccherini 			Write<uint8>((uint8)isClosed);
303ed5de868SStefano Ceccherini 		EndOp();
304ed5de868SStefano Ceccherini 	} catch (status_t &status) {
305ed5de868SStefano Ceccherini 		return status;
306ed5de868SStefano Ceccherini 	}
307ed5de868SStefano Ceccherini 	return B_OK;
308ed5de868SStefano Ceccherini }
309ed5de868SStefano Ceccherini 
310ed5de868SStefano Ceccherini 
311ed5de868SStefano Ceccherini status_t
312ed5de868SStefano Ceccherini PictureDataWriter::WriteDrawBezier(const BPoint points[4], const bool &fill)
313ed5de868SStefano Ceccherini {
314ed5de868SStefano Ceccherini 	try {
315ed5de868SStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_BEZIER : B_PIC_STROKE_BEZIER);
316ed5de868SStefano Ceccherini 		for (int32 i = 0; i < 4; i++)
317ed5de868SStefano Ceccherini 			Write<BPoint>(points[i]);
318ed5de868SStefano Ceccherini 		EndOp();
319ed5de868SStefano Ceccherini 	} catch (status_t &status) {
320ed5de868SStefano Ceccherini 		return status;
321ed5de868SStefano Ceccherini 	}
322ed5de868SStefano Ceccherini 	return B_OK;
323ed5de868SStefano Ceccherini }
324ed5de868SStefano Ceccherini 
325ed5de868SStefano Ceccherini 
326ed5de868SStefano Ceccherini status_t
327420fe80eSStefano Ceccherini PictureDataWriter::WriteStrokeLine(const BPoint &start, const BPoint &end)
328420fe80eSStefano Ceccherini {
329140334f8SStefano Ceccherini 	try {
330420fe80eSStefano Ceccherini 		BeginOp(B_PIC_STROKE_LINE);
331420fe80eSStefano Ceccherini 		Write<BPoint>(start);
332420fe80eSStefano Ceccherini 		Write<BPoint>(end);
333420fe80eSStefano Ceccherini 		EndOp();
334140334f8SStefano Ceccherini 	} catch (status_t &status) {
335140334f8SStefano Ceccherini 		return status;
336140334f8SStefano Ceccherini 	}
337420fe80eSStefano Ceccherini 	return B_OK;
338420fe80eSStefano Ceccherini }
339420fe80eSStefano Ceccherini 
340420fe80eSStefano Ceccherini 
341420fe80eSStefano Ceccherini status_t
342420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawString(const BPoint &where, const char *string,
343420fe80eSStefano Ceccherini 				   const int32 &length, const escapement_delta &escapement)
344420fe80eSStefano Ceccherini {
345140334f8SStefano Ceccherini 	try {
346420fe80eSStefano Ceccherini 		BeginOp(B_PIC_SET_PEN_LOCATION);
347420fe80eSStefano Ceccherini 		Write<BPoint>(where);
348420fe80eSStefano Ceccherini 		EndOp();
349420fe80eSStefano Ceccherini 
350420fe80eSStefano Ceccherini 		BeginOp(B_PIC_DRAW_STRING);
351420fe80eSStefano Ceccherini 		Write<float>(escapement.space);
352420fe80eSStefano Ceccherini 		Write<float>(escapement.nonspace);
3530b0ecfabSMarcus Overhagen 		//WriteData(string, length + 1); // TODO: is string 0 terminated? why is length given?
3540b0ecfabSMarcus Overhagen 		WriteData(string, length);
3550b0ecfabSMarcus Overhagen 		Write<uint8>(0);
356420fe80eSStefano Ceccherini 		EndOp();
357140334f8SStefano Ceccherini 	} catch (status_t &status) {
358140334f8SStefano Ceccherini 		return status;
359140334f8SStefano Ceccherini 	}
360420fe80eSStefano Ceccherini 
361420fe80eSStefano Ceccherini 	return B_OK;
362420fe80eSStefano Ceccherini }
363420fe80eSStefano Ceccherini 
364420fe80eSStefano Ceccherini 
365420fe80eSStefano Ceccherini status_t
366420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawShape(const int32 &opCount, const void *opList,
367420fe80eSStefano Ceccherini 				const int32 &ptCount, const void *ptList, const bool &fill)
368420fe80eSStefano Ceccherini {
369140334f8SStefano Ceccherini 	try {
370420fe80eSStefano Ceccherini 		BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE);
371420fe80eSStefano Ceccherini 		Write<int32>(opCount);
372420fe80eSStefano Ceccherini 		Write<int32>(ptCount);
3730b0ecfabSMarcus Overhagen 		WriteData(opList, opCount * sizeof(uint32));
374420fe80eSStefano Ceccherini 		WriteData(ptList, ptCount * sizeof(BPoint));
375420fe80eSStefano Ceccherini 		EndOp();
376140334f8SStefano Ceccherini 	} catch (status_t &status) {
377140334f8SStefano Ceccherini 		return status;
378140334f8SStefano Ceccherini 	}
379420fe80eSStefano Ceccherini 
380420fe80eSStefano Ceccherini 	return B_OK;
381420fe80eSStefano Ceccherini }
382420fe80eSStefano Ceccherini 
383420fe80eSStefano Ceccherini 
384420fe80eSStefano Ceccherini status_t
385420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawBitmap(const BRect &srcRect, const BRect &dstRect, const int32 &width, const int32 &height,
386420fe80eSStefano Ceccherini 				const int32 &bytesPerRow, const int32 &colorSpace, const int32 &flags,
387420fe80eSStefano Ceccherini 				const void *data, const int32 &length)
388420fe80eSStefano Ceccherini {
3890b0ecfabSMarcus Overhagen 	if (length != height * bytesPerRow)
3900b0ecfabSMarcus Overhagen 		debugger("PictureDataWriter::WriteDrawBitmap: invalid length");
391140334f8SStefano Ceccherini 	try {
392420fe80eSStefano Ceccherini 		BeginOp(B_PIC_DRAW_PIXELS);
393420fe80eSStefano Ceccherini 		Write<BRect>(srcRect);
394420fe80eSStefano Ceccherini 		Write<BRect>(dstRect);
395420fe80eSStefano Ceccherini 		Write<int32>(width);
396420fe80eSStefano Ceccherini 		Write<int32>(height);
397420fe80eSStefano Ceccherini 		Write<int32>(bytesPerRow);
398420fe80eSStefano Ceccherini 		Write<int32>(colorSpace);
399420fe80eSStefano Ceccherini 		Write<int32>(flags);
400420fe80eSStefano Ceccherini 		WriteData(data, length);
401420fe80eSStefano Ceccherini 		EndOp();
402140334f8SStefano Ceccherini 	} catch (status_t &status) {
403140334f8SStefano Ceccherini 		return status;
404140334f8SStefano Ceccherini 	}
405420fe80eSStefano Ceccherini 	return B_OK;
406420fe80eSStefano Ceccherini }
407420fe80eSStefano Ceccherini 
408420fe80eSStefano Ceccherini 
409420fe80eSStefano Ceccherini status_t
410ed5de868SStefano Ceccherini PictureDataWriter::WriteDrawPicture(const BPoint &where, const int32 &token)
411ed5de868SStefano Ceccherini {
412ed5de868SStefano Ceccherini 	// TODO: I'm not sure about this function. I think we need to attach the picture
413ed5de868SStefano Ceccherini 	// data too. The token won't be sufficient in many cases.
414ed5de868SStefano Ceccherini 	try {
415ed5de868SStefano Ceccherini 		BeginOp(B_PIC_DRAW_PICTURE);
416ed5de868SStefano Ceccherini 		Write<BPoint>(where);
417ed5de868SStefano Ceccherini 		Write<int32>(token);
418ed5de868SStefano Ceccherini 		EndOp();
419ed5de868SStefano Ceccherini 	} catch (status_t &status) {
420ed5de868SStefano Ceccherini 		return status;
421ed5de868SStefano Ceccherini 	}
422ed5de868SStefano Ceccherini 	return B_OK;
423ed5de868SStefano Ceccherini }
424ed5de868SStefano Ceccherini 
425ed5de868SStefano Ceccherini 
426ed5de868SStefano Ceccherini status_t
427feb557a6SStefano Ceccherini PictureDataWriter::WriteSetFontFamily(const font_family family)
428a3d758e3SStefano Ceccherini {
429feb557a6SStefano Ceccherini 	try {
430feb557a6SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_FAMILY);
431feb557a6SStefano Ceccherini 		WriteData(family, strlen(family));
432796e4e45SStefano Ceccherini 		Write<uint8>(0);
433feb557a6SStefano Ceccherini 		EndOp();
434feb557a6SStefano Ceccherini 	} catch (status_t &status) {
435feb557a6SStefano Ceccherini 		return status;
436feb557a6SStefano Ceccherini 	}
437a3d758e3SStefano Ceccherini 	return B_OK;
438a3d758e3SStefano Ceccherini }
439a3d758e3SStefano Ceccherini 
440a3d758e3SStefano Ceccherini 
441a3d758e3SStefano Ceccherini status_t
442feb557a6SStefano Ceccherini PictureDataWriter::WriteSetFontStyle(const font_style style)
443a3d758e3SStefano Ceccherini {
444feb557a6SStefano Ceccherini 	try {
445feb557a6SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_STYLE);
446feb557a6SStefano Ceccherini 		WriteData(style, strlen(style));
447796e4e45SStefano Ceccherini 		Write<uint8>(0);
448feb557a6SStefano Ceccherini 		EndOp();
449feb557a6SStefano Ceccherini 	} catch (status_t &status) {
450feb557a6SStefano Ceccherini 		return status;
451feb557a6SStefano Ceccherini 	}
452a3d758e3SStefano Ceccherini 	return B_OK;
453a3d758e3SStefano Ceccherini }
454a3d758e3SStefano Ceccherini 
455a3d758e3SStefano Ceccherini 
456a3d758e3SStefano Ceccherini status_t
457a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontSpacing(const int32 &spacing)
458a3d758e3SStefano Ceccherini {
459140334f8SStefano Ceccherini 	try {
460a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_SPACING);
461a3d758e3SStefano Ceccherini 		Write<int32>(spacing);
462a3d758e3SStefano Ceccherini 		EndOp();
463140334f8SStefano Ceccherini 	} catch (status_t &status) {
464140334f8SStefano Ceccherini 		return status;
465140334f8SStefano Ceccherini 	}
466a3d758e3SStefano Ceccherini 	return B_OK;
467a3d758e3SStefano Ceccherini }
468a3d758e3SStefano Ceccherini 
469a3d758e3SStefano Ceccherini 
470a3d758e3SStefano Ceccherini status_t
471a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontSize(const float &size)
472a3d758e3SStefano Ceccherini {
473140334f8SStefano Ceccherini 	try {
474a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_SIZE);
475a3d758e3SStefano Ceccherini 		Write<float>(size);
476a3d758e3SStefano Ceccherini 		EndOp();
477140334f8SStefano Ceccherini 	} catch (status_t &status) {
478140334f8SStefano Ceccherini 		return status;
479140334f8SStefano Ceccherini 	}
480a3d758e3SStefano Ceccherini 	return B_OK;
481a3d758e3SStefano Ceccherini }
482a3d758e3SStefano Ceccherini 
483a3d758e3SStefano Ceccherini 
484a3d758e3SStefano Ceccherini status_t
485a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontRotation(const float &rotation)
486a3d758e3SStefano Ceccherini {
487140334f8SStefano Ceccherini 	try {
488a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_ROTATE);
489a3d758e3SStefano Ceccherini 		Write<float>(rotation);
490a3d758e3SStefano Ceccherini 		EndOp();
491140334f8SStefano Ceccherini 	} catch (status_t &status) {
492140334f8SStefano Ceccherini 		return status;
493140334f8SStefano Ceccherini 	}
494a3d758e3SStefano Ceccherini 	return B_OK;
495a3d758e3SStefano Ceccherini }
496a3d758e3SStefano Ceccherini 
497a3d758e3SStefano Ceccherini 
498a3d758e3SStefano Ceccherini status_t
499a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontEncoding(const int32 &encoding)
500a3d758e3SStefano Ceccherini {
501140334f8SStefano Ceccherini 	try {
502a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_ENCODING);
503a3d758e3SStefano Ceccherini 		Write<int32>(encoding);
504a3d758e3SStefano Ceccherini 		EndOp();
505140334f8SStefano Ceccherini 	} catch (status_t &status) {
506140334f8SStefano Ceccherini 		return status;
507140334f8SStefano Ceccherini 	}
508a3d758e3SStefano Ceccherini 	return B_OK;
509a3d758e3SStefano Ceccherini }
510a3d758e3SStefano Ceccherini 
511a3d758e3SStefano Ceccherini 
512a3d758e3SStefano Ceccherini status_t
513a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontFlags(const int32 &flags)
514a3d758e3SStefano Ceccherini {
515140334f8SStefano Ceccherini 	try {
516a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_FLAGS);
517a3d758e3SStefano Ceccherini 		Write<int32>(flags);
518a3d758e3SStefano Ceccherini 		EndOp();
519140334f8SStefano Ceccherini 	} catch (status_t &status) {
520140334f8SStefano Ceccherini 		return status;
521140334f8SStefano Ceccherini 	}
522a3d758e3SStefano Ceccherini 	return B_OK;
523a3d758e3SStefano Ceccherini }
524a3d758e3SStefano Ceccherini 
525a3d758e3SStefano Ceccherini 
526a3d758e3SStefano Ceccherini status_t
527*b1af0a7aSStefano Ceccherini PictureDataWriter::WriteSetFontShear(const float &shear)
528a3d758e3SStefano Ceccherini {
529140334f8SStefano Ceccherini 	try {
530a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_SHEAR);
531*b1af0a7aSStefano Ceccherini 		Write<float>(shear);
532a3d758e3SStefano Ceccherini 		EndOp();
533140334f8SStefano Ceccherini 	} catch (status_t &status) {
534140334f8SStefano Ceccherini 		return status;
535140334f8SStefano Ceccherini 	}
536a3d758e3SStefano Ceccherini 	return B_OK;
537a3d758e3SStefano Ceccherini }
538a3d758e3SStefano Ceccherini 
539a3d758e3SStefano Ceccherini 
540a3d758e3SStefano Ceccherini status_t
541a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontFace(const int32 &face)
542a3d758e3SStefano Ceccherini {
543140334f8SStefano Ceccherini 	try {
544a3d758e3SStefano Ceccherini 		BeginOp(B_PIC_SET_FONT_FACE);
545a3d758e3SStefano Ceccherini 		Write<int32>(face);
546a3d758e3SStefano Ceccherini 		EndOp();
547140334f8SStefano Ceccherini 	} catch (status_t &status) {
548140334f8SStefano Ceccherini 		return status;
549140334f8SStefano Ceccherini 	}
550a3d758e3SStefano Ceccherini 	return B_OK;
551a3d758e3SStefano Ceccherini }
552a3d758e3SStefano Ceccherini 
553a3d758e3SStefano Ceccherini 
554a3d758e3SStefano Ceccherini status_t
555420fe80eSStefano Ceccherini PictureDataWriter::WritePushState()
556420fe80eSStefano Ceccherini {
557140334f8SStefano Ceccherini 	try {
558420fe80eSStefano Ceccherini 		BeginOp(B_PIC_PUSH_STATE);
559420fe80eSStefano Ceccherini 		EndOp();
560140334f8SStefano Ceccherini 	} catch (status_t &status) {
561140334f8SStefano Ceccherini 		return status;
562140334f8SStefano Ceccherini 	}
563420fe80eSStefano Ceccherini 	return B_OK;
564420fe80eSStefano Ceccherini }
565420fe80eSStefano Ceccherini 
566420fe80eSStefano Ceccherini 
567420fe80eSStefano Ceccherini status_t
568420fe80eSStefano Ceccherini PictureDataWriter::WritePopState()
569420fe80eSStefano Ceccherini {
570140334f8SStefano Ceccherini 	try {
571420fe80eSStefano Ceccherini 		BeginOp(B_PIC_POP_STATE);
572420fe80eSStefano Ceccherini 		EndOp();
573140334f8SStefano Ceccherini 	} catch (status_t &status) {
574140334f8SStefano Ceccherini 		return status;
575140334f8SStefano Ceccherini 	}
576420fe80eSStefano Ceccherini 	return B_OK;
577420fe80eSStefano Ceccherini }
578420fe80eSStefano Ceccherini 
579420fe80eSStefano Ceccherini 
580420fe80eSStefano Ceccherini // private
581140334f8SStefano Ceccherini void
582420fe80eSStefano Ceccherini PictureDataWriter::BeginOp(const int16 &op)
583420fe80eSStefano Ceccherini {
584140334f8SStefano Ceccherini 	if (fData == NULL)
58584c2abeeSStefano Ceccherini 		THROW_ERROR(B_NO_INIT);
586140334f8SStefano Ceccherini 
587420fe80eSStefano Ceccherini 	fStack.push(fData->Position());
588420fe80eSStefano Ceccherini 	fData->Write(&op, sizeof(op));
589420fe80eSStefano Ceccherini 
590420fe80eSStefano Ceccherini 	// Init the size of the opcode block to 0
591420fe80eSStefano Ceccherini 	size_t size = 0;
592420fe80eSStefano Ceccherini 	fData->Write(&size, sizeof(size));
593420fe80eSStefano Ceccherini }
594420fe80eSStefano Ceccherini 
595420fe80eSStefano Ceccherini 
596140334f8SStefano Ceccherini void
597420fe80eSStefano Ceccherini PictureDataWriter::EndOp()
598420fe80eSStefano Ceccherini {
599140334f8SStefano Ceccherini 	if (fData == NULL)
60084c2abeeSStefano Ceccherini 		THROW_ERROR(B_NO_INIT);
601140334f8SStefano Ceccherini 
602420fe80eSStefano Ceccherini 	off_t curPos = fData->Position();
603420fe80eSStefano Ceccherini 	off_t stackPos = fStack.top();
604420fe80eSStefano Ceccherini 	fStack.pop();
605420fe80eSStefano Ceccherini 
606420fe80eSStefano Ceccherini 	// The size of the op is calculated like this:
607420fe80eSStefano Ceccherini 	// current position on the stream minus the position on the stack,
608420fe80eSStefano Ceccherini 	// minus the space occupied by the op code itself (int16)
609420fe80eSStefano Ceccherini 	// and the space occupied by the size field (size_t)
610420fe80eSStefano Ceccherini 	size_t size = curPos - stackPos - sizeof(size_t) - sizeof(int16);
611420fe80eSStefano Ceccherini 
612420fe80eSStefano Ceccherini 	// Size was set to 0 in BeginOp(). Now we overwrite it with the correct value
613420fe80eSStefano Ceccherini 	fData->Seek(stackPos + sizeof(int16), SEEK_SET);
614420fe80eSStefano Ceccherini 	fData->Write(&size, sizeof(size));
615420fe80eSStefano Ceccherini 	fData->Seek(curPos, SEEK_SET);
616420fe80eSStefano Ceccherini }
617420fe80eSStefano Ceccherini 
618420fe80eSStefano Ceccherini 
619140334f8SStefano Ceccherini void
620420fe80eSStefano Ceccherini PictureDataWriter::WriteData(const void *data, size_t size)
621420fe80eSStefano Ceccherini {
622140334f8SStefano Ceccherini 	ssize_t result = fData->Write(data, size);
623140334f8SStefano Ceccherini 	if (result < 0)
62484c2abeeSStefano Ceccherini 		THROW_ERROR(result);
625ed5de868SStefano Ceccherini 	if ((size_t)result != size)
62684c2abeeSStefano Ceccherini 		THROW_ERROR(B_IO_ERROR);
627420fe80eSStefano Ceccherini }
628