xref: /haiku/src/kits/interface/PictureDataWriter.cpp (revision a3d758e3690cd335fb1afcd5b4d4c1c67def045a)
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 
9420fe80eSStefano Ceccherini #include <DataIO.h>
10420fe80eSStefano Ceccherini #include <Point.h>
11420fe80eSStefano Ceccherini #include <Rect.h>
12420fe80eSStefano Ceccherini 
13420fe80eSStefano Ceccherini #include <PictureDataWriter.h>
14420fe80eSStefano Ceccherini #include <PictureProtocol.h>
15420fe80eSStefano Ceccherini 
16252f4767SRyan Leavengood #include <stdio.h>
17252f4767SRyan Leavengood 
18420fe80eSStefano Ceccherini PictureDataWriter::PictureDataWriter(BPositionIO *data)
19420fe80eSStefano Ceccherini 	:
20420fe80eSStefano Ceccherini 	fData(data)
21420fe80eSStefano Ceccherini {
22420fe80eSStefano Ceccherini }
23420fe80eSStefano Ceccherini 
24420fe80eSStefano Ceccherini 
25420fe80eSStefano Ceccherini status_t
26420fe80eSStefano Ceccherini PictureDataWriter::WriteSetOrigin(const BPoint &point)
27420fe80eSStefano Ceccherini {
28420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_ORIGIN);
29420fe80eSStefano Ceccherini 	Write<BPoint>(point);
30420fe80eSStefano Ceccherini 	EndOp();
31420fe80eSStefano Ceccherini 	return B_OK;
32420fe80eSStefano Ceccherini }
33420fe80eSStefano Ceccherini 
34420fe80eSStefano Ceccherini 
35420fe80eSStefano Ceccherini status_t
36420fe80eSStefano Ceccherini PictureDataWriter::WriteInvertRect(const BRect &rect)
37420fe80eSStefano Ceccherini {
38420fe80eSStefano Ceccherini 	WriteSetDrawingMode(B_OP_INVERT);
39420fe80eSStefano Ceccherini 
40420fe80eSStefano Ceccherini 	BeginOp(B_PIC_FILL_RECT);
41420fe80eSStefano Ceccherini 	Write<BRect>(rect);
42420fe80eSStefano Ceccherini 	EndOp();
43420fe80eSStefano Ceccherini 
44420fe80eSStefano Ceccherini 	WriteSetDrawingMode(B_OP_COPY);
45420fe80eSStefano Ceccherini 	return B_OK;
46420fe80eSStefano Ceccherini }
47420fe80eSStefano Ceccherini 
48420fe80eSStefano Ceccherini 
49420fe80eSStefano Ceccherini status_t
50420fe80eSStefano Ceccherini PictureDataWriter::WriteSetDrawingMode(const drawing_mode &mode)
51420fe80eSStefano Ceccherini {
52420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_DRAWING_MODE);
53420fe80eSStefano Ceccherini 	Write<int16>((int16)mode);
54420fe80eSStefano Ceccherini 	EndOp();
55420fe80eSStefano Ceccherini 	return B_OK;
56420fe80eSStefano Ceccherini }
57420fe80eSStefano Ceccherini 
58420fe80eSStefano Ceccherini 
59420fe80eSStefano Ceccherini status_t
60420fe80eSStefano Ceccherini PictureDataWriter::WriteSetPenSize(const float &penSize)
61420fe80eSStefano Ceccherini {
62420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_PEN_SIZE);
63420fe80eSStefano Ceccherini 	Write<float>(penSize);
64420fe80eSStefano Ceccherini 	EndOp();
65420fe80eSStefano Ceccherini 	return B_OK;
66420fe80eSStefano Ceccherini }
67420fe80eSStefano Ceccherini 
68420fe80eSStefano Ceccherini 
69420fe80eSStefano Ceccherini status_t
70420fe80eSStefano Ceccherini PictureDataWriter::WriteSetLineMode(const cap_mode &cap, const join_mode &join, const float &miterLimit)
71420fe80eSStefano Ceccherini {
72420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_LINE_MODE);
73420fe80eSStefano Ceccherini 	Write<int16>((int16)cap);
74420fe80eSStefano Ceccherini 	Write<int16>((int16)join);
75420fe80eSStefano Ceccherini 	Write<float>(miterLimit);
76420fe80eSStefano Ceccherini 	EndOp();
77420fe80eSStefano Ceccherini 	return B_OK;
78420fe80eSStefano Ceccherini }
79420fe80eSStefano Ceccherini 
80420fe80eSStefano Ceccherini 
81420fe80eSStefano Ceccherini status_t
82420fe80eSStefano Ceccherini PictureDataWriter::WriteSetScale(const float &scale)
83420fe80eSStefano Ceccherini {
84420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_SCALE);
85420fe80eSStefano Ceccherini 	Write<float>(scale);
86420fe80eSStefano Ceccherini 	EndOp();
87420fe80eSStefano Ceccherini 	return B_OK;
88420fe80eSStefano Ceccherini }
89420fe80eSStefano Ceccherini 
90420fe80eSStefano Ceccherini 
91420fe80eSStefano Ceccherini status_t
92420fe80eSStefano Ceccherini PictureDataWriter::WriteSetHighColor(const rgb_color &color)
93420fe80eSStefano Ceccherini {
94420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_FORE_COLOR);
95420fe80eSStefano Ceccherini 	Write<rgb_color>(color);
96420fe80eSStefano Ceccherini 	EndOp();
97420fe80eSStefano Ceccherini 	return B_OK;
98420fe80eSStefano Ceccherini }
99420fe80eSStefano Ceccherini 
100420fe80eSStefano Ceccherini 
101420fe80eSStefano Ceccherini status_t
102420fe80eSStefano Ceccherini PictureDataWriter::WriteSetLowColor(const rgb_color &color)
103420fe80eSStefano Ceccherini {
104420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_BACK_COLOR);
105420fe80eSStefano Ceccherini 	Write<rgb_color>(color);
106420fe80eSStefano Ceccherini 	EndOp();
107420fe80eSStefano Ceccherini 	return B_OK;
108420fe80eSStefano Ceccherini }
109420fe80eSStefano Ceccherini 
110420fe80eSStefano Ceccherini 
111420fe80eSStefano Ceccherini status_t
112420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawRect(const BRect &rect, const bool &fill)
113420fe80eSStefano Ceccherini {
114420fe80eSStefano Ceccherini 	BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT);
115420fe80eSStefano Ceccherini 	Write<BRect>(rect);
116420fe80eSStefano Ceccherini 	EndOp();
117420fe80eSStefano Ceccherini 	return B_OK;
118420fe80eSStefano Ceccherini }
119420fe80eSStefano Ceccherini 
120420fe80eSStefano Ceccherini 
121420fe80eSStefano Ceccherini status_t
122420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawRoundRect(const BRect &rect, const BPoint &radius, const bool &fill)
123420fe80eSStefano Ceccherini {
124420fe80eSStefano Ceccherini 	BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT);
125420fe80eSStefano Ceccherini 	Write<BRect>(rect);
126420fe80eSStefano Ceccherini 	Write<BPoint>(radius);
127420fe80eSStefano Ceccherini 	EndOp();
128420fe80eSStefano Ceccherini 	return B_OK;
129420fe80eSStefano Ceccherini }
130420fe80eSStefano Ceccherini 
131420fe80eSStefano Ceccherini 
132420fe80eSStefano Ceccherini status_t
133420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawEllipse(const BRect &rect, const bool &fill)
134420fe80eSStefano Ceccherini {
135420fe80eSStefano Ceccherini 	BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE);
136420fe80eSStefano Ceccherini 	Write<BRect>(rect);
137420fe80eSStefano Ceccherini 	EndOp();
138420fe80eSStefano Ceccherini 	return B_OK;
139420fe80eSStefano Ceccherini }
140420fe80eSStefano Ceccherini 
141420fe80eSStefano Ceccherini 
142420fe80eSStefano Ceccherini status_t
143420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawArc(const BPoint &center, const BPoint &radius,
144420fe80eSStefano Ceccherini 				const float &startTheta, const float &arcTheta, const bool &fill)
145420fe80eSStefano Ceccherini {
146420fe80eSStefano Ceccherini 	BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC);
147420fe80eSStefano Ceccherini 	Write<BPoint>(center);
148420fe80eSStefano Ceccherini 	Write<BPoint>(radius);
149420fe80eSStefano Ceccherini 	Write<float>(startTheta);
150420fe80eSStefano Ceccherini 	Write<float>(arcTheta);
151420fe80eSStefano Ceccherini 	EndOp();
152420fe80eSStefano Ceccherini 	return B_OK;
153420fe80eSStefano Ceccherini }
154420fe80eSStefano Ceccherini 
155420fe80eSStefano Ceccherini 
156420fe80eSStefano Ceccherini status_t
157420fe80eSStefano Ceccherini PictureDataWriter::WriteStrokeLine(const BPoint &start, const BPoint &end)
158420fe80eSStefano Ceccherini {
159420fe80eSStefano Ceccherini 	BeginOp(B_PIC_STROKE_LINE);
160420fe80eSStefano Ceccherini 	Write<BPoint>(start);
161420fe80eSStefano Ceccherini 	Write<BPoint>(end);
162420fe80eSStefano Ceccherini 	EndOp();
163420fe80eSStefano Ceccherini 	return B_OK;
164420fe80eSStefano Ceccherini }
165420fe80eSStefano Ceccherini 
166420fe80eSStefano Ceccherini 
167420fe80eSStefano Ceccherini status_t
168420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawString(const BPoint &where, const char *string,
169420fe80eSStefano Ceccherini 				   const int32 &length, const escapement_delta &escapement)
170420fe80eSStefano Ceccherini {
171420fe80eSStefano Ceccherini 	BeginOp(B_PIC_SET_PEN_LOCATION);
172420fe80eSStefano Ceccherini 	Write<BPoint>(where);
173420fe80eSStefano Ceccherini 	EndOp();
174420fe80eSStefano Ceccherini 
175420fe80eSStefano Ceccherini 	BeginOp(B_PIC_DRAW_STRING);
176420fe80eSStefano Ceccherini 	Write<float>(escapement.space);
177420fe80eSStefano Ceccherini 	Write<float>(escapement.nonspace);
1780b0ecfabSMarcus Overhagen 	//WriteData(string, length + 1); // TODO: is string 0 terminated? why is length given?
1790b0ecfabSMarcus Overhagen 	WriteData(string, length);
1800b0ecfabSMarcus Overhagen 	Write<uint8>(0);
181420fe80eSStefano Ceccherini 	EndOp();
182420fe80eSStefano Ceccherini 
183420fe80eSStefano Ceccherini 	return B_OK;
184420fe80eSStefano Ceccherini }
185420fe80eSStefano Ceccherini 
186420fe80eSStefano Ceccherini 
187420fe80eSStefano Ceccherini status_t
188420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawShape(const int32 &opCount, const void *opList,
189420fe80eSStefano Ceccherini 				const int32 &ptCount, const void *ptList, const bool &fill)
190420fe80eSStefano Ceccherini {
191420fe80eSStefano Ceccherini 	BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE);
192420fe80eSStefano Ceccherini 	Write<int32>(opCount);
193420fe80eSStefano Ceccherini 	Write<int32>(ptCount);
1940b0ecfabSMarcus Overhagen 	WriteData(opList, opCount * sizeof(uint32));
195420fe80eSStefano Ceccherini 	WriteData(ptList, ptCount * sizeof(BPoint));
196420fe80eSStefano Ceccherini 	EndOp();
197420fe80eSStefano Ceccherini 
198420fe80eSStefano Ceccherini 	return B_OK;
199420fe80eSStefano Ceccherini }
200420fe80eSStefano Ceccherini 
201420fe80eSStefano Ceccherini 
202420fe80eSStefano Ceccherini status_t
203420fe80eSStefano Ceccherini PictureDataWriter::WriteDrawBitmap(const BRect &srcRect, const BRect &dstRect, const int32 &width, const int32 &height,
204420fe80eSStefano Ceccherini 				const int32 &bytesPerRow, const int32 &colorSpace, const int32 &flags,
205420fe80eSStefano Ceccherini 				const void *data, const int32 &length)
206420fe80eSStefano Ceccherini {
2070b0ecfabSMarcus Overhagen 	if (length != height * bytesPerRow)
2080b0ecfabSMarcus Overhagen 		debugger("PictureDataWriter::WriteDrawBitmap: invalid length");
209420fe80eSStefano Ceccherini 	BeginOp(B_PIC_DRAW_PIXELS);
210420fe80eSStefano Ceccherini 	Write<BRect>(srcRect);
211420fe80eSStefano Ceccherini 	Write<BRect>(dstRect);
212420fe80eSStefano Ceccherini 	Write<int32>(width);
213420fe80eSStefano Ceccherini 	Write<int32>(height);
214420fe80eSStefano Ceccherini 	Write<int32>(bytesPerRow);
215420fe80eSStefano Ceccherini 	Write<int32>(colorSpace);
216420fe80eSStefano Ceccherini 	Write<int32>(flags);
217420fe80eSStefano Ceccherini 	WriteData(data, length);
218420fe80eSStefano Ceccherini 	EndOp();
219420fe80eSStefano Ceccherini 	return B_OK;
220420fe80eSStefano Ceccherini }
221420fe80eSStefano Ceccherini 
222420fe80eSStefano Ceccherini 
223420fe80eSStefano Ceccherini status_t
224*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontFamily(const font_family &family)
225*a3d758e3SStefano Ceccherini {
226*a3d758e3SStefano Ceccherini 	/*BeginOp(B_PIC_SET_FONT_FAMILY);
227*a3d758e3SStefano Ceccherini 	Write(
228*a3d758e3SStefano Ceccherini 	EndOp();*/
229*a3d758e3SStefano Ceccherini 	return B_OK;
230*a3d758e3SStefano Ceccherini }
231*a3d758e3SStefano Ceccherini 
232*a3d758e3SStefano Ceccherini 
233*a3d758e3SStefano Ceccherini status_t
234*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontStyle(const font_style &style)
235*a3d758e3SStefano Ceccherini {
236*a3d758e3SStefano Ceccherini 	/*BeginOp(B_PIC_SET_FONT_STYLE);
237*a3d758e3SStefano Ceccherini 	Write(
238*a3d758e3SStefano Ceccherini 	EndOp();*/
239*a3d758e3SStefano Ceccherini 	return B_OK;
240*a3d758e3SStefano Ceccherini }
241*a3d758e3SStefano Ceccherini 
242*a3d758e3SStefano Ceccherini 
243*a3d758e3SStefano Ceccherini status_t
244*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontSpacing(const int32 &spacing)
245*a3d758e3SStefano Ceccherini {
246*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_SPACING);
247*a3d758e3SStefano Ceccherini 	Write<int32>(spacing);
248*a3d758e3SStefano Ceccherini 	EndOp();
249*a3d758e3SStefano Ceccherini 	return B_OK;
250*a3d758e3SStefano Ceccherini }
251*a3d758e3SStefano Ceccherini 
252*a3d758e3SStefano Ceccherini 
253*a3d758e3SStefano Ceccherini status_t
254*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontSize(const float &size)
255*a3d758e3SStefano Ceccherini {
256*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_SIZE);
257*a3d758e3SStefano Ceccherini 	Write<float>(size);
258*a3d758e3SStefano Ceccherini 	EndOp();
259*a3d758e3SStefano Ceccherini 	return B_OK;
260*a3d758e3SStefano Ceccherini }
261*a3d758e3SStefano Ceccherini 
262*a3d758e3SStefano Ceccherini 
263*a3d758e3SStefano Ceccherini status_t
264*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontRotation(const float &rotation)
265*a3d758e3SStefano Ceccherini {
266*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_ROTATE);
267*a3d758e3SStefano Ceccherini 	Write<float>(rotation);
268*a3d758e3SStefano Ceccherini 	EndOp();
269*a3d758e3SStefano Ceccherini 	return B_OK;
270*a3d758e3SStefano Ceccherini }
271*a3d758e3SStefano Ceccherini 
272*a3d758e3SStefano Ceccherini 
273*a3d758e3SStefano Ceccherini status_t
274*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontEncoding(const int32 &encoding)
275*a3d758e3SStefano Ceccherini {
276*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_ENCODING);
277*a3d758e3SStefano Ceccherini 	Write<int32>(encoding);
278*a3d758e3SStefano Ceccherini 	EndOp();
279*a3d758e3SStefano Ceccherini 	return B_OK;
280*a3d758e3SStefano Ceccherini }
281*a3d758e3SStefano Ceccherini 
282*a3d758e3SStefano Ceccherini 
283*a3d758e3SStefano Ceccherini status_t
284*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontFlags(const int32 &flags)
285*a3d758e3SStefano Ceccherini {
286*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_FLAGS);
287*a3d758e3SStefano Ceccherini 	Write<int32>(flags);
288*a3d758e3SStefano Ceccherini 	EndOp();
289*a3d758e3SStefano Ceccherini 	return B_OK;
290*a3d758e3SStefano Ceccherini }
291*a3d758e3SStefano Ceccherini 
292*a3d758e3SStefano Ceccherini 
293*a3d758e3SStefano Ceccherini status_t
294*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontShear(const int32 &shear)
295*a3d758e3SStefano Ceccherini {
296*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_SHEAR);
297*a3d758e3SStefano Ceccherini 	Write<int32>(shear);
298*a3d758e3SStefano Ceccherini 	EndOp();
299*a3d758e3SStefano Ceccherini 	return B_OK;
300*a3d758e3SStefano Ceccherini }
301*a3d758e3SStefano Ceccherini 
302*a3d758e3SStefano Ceccherini 
303*a3d758e3SStefano Ceccherini status_t
304*a3d758e3SStefano Ceccherini PictureDataWriter::WriteSetFontFace(const int32 &face)
305*a3d758e3SStefano Ceccherini {
306*a3d758e3SStefano Ceccherini 	BeginOp(B_PIC_SET_FONT_FACE);
307*a3d758e3SStefano Ceccherini 	Write<int32>(face);
308*a3d758e3SStefano Ceccherini 	EndOp();
309*a3d758e3SStefano Ceccherini 	return B_OK;
310*a3d758e3SStefano Ceccherini }
311*a3d758e3SStefano Ceccherini 
312*a3d758e3SStefano Ceccherini 
313*a3d758e3SStefano Ceccherini status_t
314420fe80eSStefano Ceccherini PictureDataWriter::WritePushState()
315420fe80eSStefano Ceccherini {
316420fe80eSStefano Ceccherini 	BeginOp(B_PIC_PUSH_STATE);
317420fe80eSStefano Ceccherini 	EndOp();
318420fe80eSStefano Ceccherini 	return B_OK;
319420fe80eSStefano Ceccherini }
320420fe80eSStefano Ceccherini 
321420fe80eSStefano Ceccherini 
322420fe80eSStefano Ceccherini status_t
323420fe80eSStefano Ceccherini PictureDataWriter::WritePopState()
324420fe80eSStefano Ceccherini {
325420fe80eSStefano Ceccherini 	BeginOp(B_PIC_POP_STATE);
326420fe80eSStefano Ceccherini 	EndOp();
327420fe80eSStefano Ceccherini 	return B_OK;
328420fe80eSStefano Ceccherini }
329420fe80eSStefano Ceccherini 
330420fe80eSStefano Ceccherini 
331420fe80eSStefano Ceccherini // private
332420fe80eSStefano Ceccherini status_t
333420fe80eSStefano Ceccherini PictureDataWriter::BeginOp(const int16 &op)
334420fe80eSStefano Ceccherini {
335420fe80eSStefano Ceccherini 	fStack.push(fData->Position());
336420fe80eSStefano Ceccherini 	fData->Write(&op, sizeof(op));
337420fe80eSStefano Ceccherini 
338420fe80eSStefano Ceccherini 	// Init the size of the opcode block to 0
339420fe80eSStefano Ceccherini 	size_t size = 0;
340420fe80eSStefano Ceccherini 	fData->Write(&size, sizeof(size));
341420fe80eSStefano Ceccherini 	return B_OK;
342420fe80eSStefano Ceccherini }
343420fe80eSStefano Ceccherini 
344420fe80eSStefano Ceccherini 
345420fe80eSStefano Ceccherini status_t
346420fe80eSStefano Ceccherini PictureDataWriter::EndOp()
347420fe80eSStefano Ceccherini {
348420fe80eSStefano Ceccherini 	off_t curPos = fData->Position();
349420fe80eSStefano Ceccherini 	off_t stackPos = fStack.top();
350420fe80eSStefano Ceccherini 	fStack.pop();
351420fe80eSStefano Ceccherini 
352420fe80eSStefano Ceccherini 	// The size of the op is calculated like this:
353420fe80eSStefano Ceccherini 	// current position on the stream minus the position on the stack,
354420fe80eSStefano Ceccherini 	// minus the space occupied by the op code itself (int16)
355420fe80eSStefano Ceccherini 	// and the space occupied by the size field (size_t)
356420fe80eSStefano Ceccherini 	size_t size = curPos - stackPos - sizeof(size_t) - sizeof(int16);
357420fe80eSStefano Ceccherini 
358420fe80eSStefano Ceccherini 	// Size was set to 0 in BeginOp(). Now we overwrite it with the correct value
359420fe80eSStefano Ceccherini 	fData->Seek(stackPos + sizeof(int16), SEEK_SET);
360420fe80eSStefano Ceccherini 	fData->Write(&size, sizeof(size));
361420fe80eSStefano Ceccherini 	fData->Seek(curPos, SEEK_SET);
362420fe80eSStefano Ceccherini 	return B_OK;
363420fe80eSStefano Ceccherini }
364420fe80eSStefano Ceccherini 
365420fe80eSStefano Ceccherini 
366420fe80eSStefano Ceccherini status_t
367420fe80eSStefano Ceccherini PictureDataWriter::WriteData(const void *data, size_t size)
368420fe80eSStefano Ceccherini {
369420fe80eSStefano Ceccherini 	return fData->Write(data, size);
370420fe80eSStefano Ceccherini }
371