tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / interface / PictureDataWriter.cpp
blob3f9f5c911c2036876d7ccd0b394d972333f14e96
1 /*
2 * Copyright 2006-2009 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stefano Ceccherini, stefano.ceccherini@gmail.com
7 */
9 #include <PictureDataWriter.h>
11 #include <stdio.h>
12 #include <string.h>
14 #include <DataIO.h>
15 #include <Point.h>
16 #include <Rect.h>
17 #include <Region.h>
19 #include <PictureProtocol.h>
21 #define THROW_ERROR(error) throw (status_t)(error)
24 // TODO: Review writing of strings. AFAIK in the picture data format
25 // They are not supposed to be NULL terminated
26 // (at least, it's not mandatory) so we should write their size too.
27 PictureDataWriter::PictureDataWriter()
29 fData(NULL)
34 PictureDataWriter::PictureDataWriter(BPositionIO* data)
36 fData(data)
41 PictureDataWriter::~PictureDataWriter()
46 status_t
47 PictureDataWriter::SetTo(BPositionIO* data)
49 if (data == NULL)
50 return B_BAD_VALUE;
52 fData = data;
54 return B_OK;
58 status_t
59 PictureDataWriter::WriteSetOrigin(const BPoint& point)
61 try {
62 BeginOp(B_PIC_SET_ORIGIN);
63 Write<BPoint>(point);
64 EndOp();
65 } catch (status_t& status) {
66 return status;
69 return B_OK;
73 status_t
74 PictureDataWriter::WriteInvertRect(const BRect& rect)
76 try {
77 WriteSetDrawingMode(B_OP_INVERT);
79 BeginOp(B_PIC_FILL_RECT);
80 Write<BRect>(rect);
81 EndOp();
83 WriteSetDrawingMode(B_OP_COPY);
84 } catch (status_t& status) {
85 return status;
88 return B_OK;
92 status_t
93 PictureDataWriter::WriteSetDrawingMode(const drawing_mode& mode)
95 try {
96 BeginOp(B_PIC_SET_DRAWING_MODE);
97 Write<int16>((int16)mode);
98 EndOp();
99 } catch (status_t& status) {
100 return status;
103 return B_OK;
107 status_t
108 PictureDataWriter::WriteSetPenLocation(const BPoint& point)
110 try {
111 BeginOp(B_PIC_SET_PEN_LOCATION);
112 Write<BPoint>(point);
113 EndOp();
114 } catch (status_t& status) {
115 return status;
118 return B_OK;
122 status_t
123 PictureDataWriter::WriteSetPenSize(const float& penSize)
125 try {
126 BeginOp(B_PIC_SET_PEN_SIZE);
127 Write<float>(penSize);
128 EndOp();
129 } catch (status_t& status) {
130 return status;
133 return B_OK;
137 status_t
138 PictureDataWriter::WriteSetLineMode(const cap_mode& cap, const join_mode& join,
139 const float& miterLimit)
141 try {
142 BeginOp(B_PIC_SET_LINE_MODE);
143 Write<int16>((int16)cap);
144 Write<int16>((int16)join);
145 Write<float>(miterLimit);
146 EndOp();
147 } catch (status_t& status) {
148 return status;
151 return B_OK;
155 status_t
156 PictureDataWriter::WriteSetScale(const float& scale)
158 try {
159 BeginOp(B_PIC_SET_SCALE);
160 Write<float>(scale);
161 EndOp();
162 } catch (status_t& status) {
163 return status;
166 return B_OK;
170 status_t
171 PictureDataWriter::WriteSetTransform(BAffineTransform transform)
173 try {
174 BeginOp(B_PIC_SET_TRANSFORM);
175 Write<BAffineTransform>(transform);
176 EndOp();
177 } catch (status_t& status) {
178 return status;
181 return B_OK;
185 status_t
186 PictureDataWriter::WriteSetPattern(const ::pattern& pattern)
188 try {
189 BeginOp(B_PIC_SET_STIPLE_PATTERN);
190 Write< ::pattern>(pattern);
191 EndOp();
192 } catch (status_t& status) {
193 return status;
196 return B_OK;
200 status_t
201 PictureDataWriter::WriteSetClipping(const BRegion& region)
203 // TODO: I don't know if it's compatible with R5's BPicture version
204 try {
205 const int32 numRects = region.CountRects();
206 if (numRects > 0 && region.Frame().IsValid()) {
207 BeginOp(B_PIC_SET_CLIPPING_RECTS);
208 Write<uint32>(numRects);
209 for (int32 i = 0; i < numRects; i++)
210 Write<BRect>(region.RectAt(i));
212 EndOp();
213 } else
214 WriteClearClipping();
215 } catch (status_t& status) {
216 return status;
219 return B_OK;
223 status_t
224 PictureDataWriter::WriteClearClipping()
226 try {
227 BeginOp(B_PIC_CLEAR_CLIPPING_RECTS);
228 EndOp();
229 } catch (status_t& status) {
230 return status;
233 return B_OK;
237 status_t
238 PictureDataWriter::WriteSetHighColor(const rgb_color& color)
240 try {
241 BeginOp(B_PIC_SET_FORE_COLOR);
242 Write<rgb_color>(color);
243 EndOp();
244 } catch (status_t& status) {
245 return status;
248 return B_OK;
252 status_t
253 PictureDataWriter::WriteSetLowColor(const rgb_color& color)
255 try {
256 BeginOp(B_PIC_SET_BACK_COLOR);
257 Write<rgb_color>(color);
258 EndOp();
259 } catch (status_t& status) {
260 return status;
263 return B_OK;
267 status_t
268 PictureDataWriter::WriteDrawRect(const BRect& rect, const bool& fill)
270 try {
271 BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT);
272 Write<BRect>(rect);
273 EndOp();
274 } catch (status_t& status) {
275 return status;
278 return B_OK;
282 status_t
283 PictureDataWriter::WriteDrawRoundRect(const BRect& rect, const BPoint& radius,
284 const bool& fill)
286 try {
287 BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT);
288 Write<BRect>(rect);
289 Write<BPoint>(radius);
290 EndOp();
291 } catch (status_t& status) {
292 return status;
295 return B_OK;
299 status_t
300 PictureDataWriter::WriteDrawEllipse(const BRect& rect, const bool& fill)
302 try {
303 BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE);
304 Write<BRect>(rect);
305 EndOp();
306 } catch (status_t& status) {
307 return status;
310 return B_OK;
314 status_t
315 PictureDataWriter::WriteDrawArc(const BPoint& center, const BPoint& radius,
316 const float& startTheta, const float& arcTheta, const bool& fill)
318 try {
319 BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC);
320 Write<BPoint>(center);
321 Write<BPoint>(radius);
322 Write<float>(startTheta);
323 Write<float>(arcTheta);
324 EndOp();
325 } catch (status_t& status) {
326 return status;
329 return B_OK;
333 status_t
334 PictureDataWriter::WriteDrawPolygon(const int32& numPoints, BPoint* points,
335 const bool& isClosed, const bool& fill)
337 try {
338 BeginOp(fill ? B_PIC_FILL_POLYGON : B_PIC_STROKE_POLYGON);
339 Write<int32>(numPoints);
340 for (int32 i = 0; i < numPoints; i++)
341 Write<BPoint>(points[i]);
343 if (!fill)
344 Write<uint8>((uint8)isClosed);
346 EndOp();
347 } catch (status_t& status) {
348 return status;
351 return B_OK;
355 status_t
356 PictureDataWriter::WriteDrawBezier(const BPoint points[4], const bool& fill)
358 try {
359 BeginOp(fill ? B_PIC_FILL_BEZIER : B_PIC_STROKE_BEZIER);
360 for (int32 i = 0; i < 4; i++)
361 Write<BPoint>(points[i]);
363 EndOp();
364 } catch (status_t& status) {
365 return status;
368 return B_OK;
372 status_t
373 PictureDataWriter::WriteStrokeLine(const BPoint& start, const BPoint& end)
375 try {
376 BeginOp(B_PIC_STROKE_LINE);
377 Write<BPoint>(start);
378 Write<BPoint>(end);
379 EndOp();
380 } catch (status_t& status) {
381 return status;
384 return B_OK;
388 status_t
389 PictureDataWriter::WriteDrawString(const BPoint& where, const char* string,
390 const int32& length, const escapement_delta& escapement)
392 try {
393 BeginOp(B_PIC_SET_PEN_LOCATION);
394 Write<BPoint>(where);
395 EndOp();
397 BeginOp(B_PIC_DRAW_STRING);
398 Write<float>(escapement.space);
399 Write<float>(escapement.nonspace);
400 //WriteData(string, length + 1);
401 // TODO: is string 0 terminated? why is length given?
402 WriteData(string, length);
403 Write<uint8>(0);
404 EndOp();
405 } catch (status_t& status) {
406 return status;
409 return B_OK;
413 status_t
414 PictureDataWriter::WriteDrawShape(const int32& opCount, const void* opList,
415 const int32& ptCount, const void* ptList, const bool& fill)
417 try {
418 BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE);
419 Write<int32>(opCount);
420 Write<int32>(ptCount);
421 WriteData(opList, opCount * sizeof(uint32));
422 WriteData(ptList, ptCount * sizeof(BPoint));
423 EndOp();
424 } catch (status_t& status) {
425 return status;
428 return B_OK;
432 status_t
433 PictureDataWriter::WriteDrawBitmap(const BRect& srcRect, const BRect& dstRect,
434 const int32& width, const int32& height, const int32& bytesPerRow,
435 const int32& colorSpace, const int32& flags, const void* data,
436 const int32& length)
438 if (length != height * bytesPerRow)
439 debugger("PictureDataWriter::WriteDrawBitmap: invalid length");
440 try {
441 BeginOp(B_PIC_DRAW_PIXELS);
442 Write<BRect>(srcRect);
443 Write<BRect>(dstRect);
444 Write<int32>(width);
445 Write<int32>(height);
446 Write<int32>(bytesPerRow);
447 Write<int32>(colorSpace);
448 Write<int32>(flags);
449 WriteData(data, length);
450 EndOp();
451 } catch (status_t& status) {
452 return status;
455 return B_OK;
459 status_t
460 PictureDataWriter::WriteDrawPicture(const BPoint& where, const int32& token)
462 // TODO: I'm not sure about this function. I think we need
463 // to attach the picture data too.
464 // The token won't be sufficient in many cases (for example, when
465 // we archive/flatten the picture.
466 try {
467 BeginOp(B_PIC_DRAW_PICTURE);
468 Write<BPoint>(where);
469 Write<int32>(token);
470 EndOp();
471 } catch (status_t& status) {
472 return status;
475 return B_OK;
479 status_t
480 PictureDataWriter::WriteSetFontFamily(const font_family family)
482 try {
483 BeginOp(B_PIC_SET_FONT_FAMILY);
484 WriteData(family, strlen(family));
485 Write<uint8>(0);
486 EndOp();
487 } catch (status_t& status) {
488 return status;
491 return B_OK;
495 status_t
496 PictureDataWriter::WriteSetFontStyle(const font_style style)
498 try {
499 BeginOp(B_PIC_SET_FONT_STYLE);
500 WriteData(style, strlen(style));
501 Write<uint8>(0);
502 EndOp();
503 } catch (status_t& status) {
504 return status;
507 return B_OK;
511 status_t
512 PictureDataWriter::WriteSetFontSpacing(const int32& spacing)
514 try {
515 BeginOp(B_PIC_SET_FONT_SPACING);
516 Write<int32>(spacing);
517 EndOp();
518 } catch (status_t& status) {
519 return status;
522 return B_OK;
526 status_t
527 PictureDataWriter::WriteSetFontSize(const float& size)
529 try {
530 BeginOp(B_PIC_SET_FONT_SIZE);
531 Write<float>(size);
532 EndOp();
533 } catch (status_t& status) {
534 return status;
537 return B_OK;
541 status_t
542 PictureDataWriter::WriteSetFontRotation(const float& rotation)
544 try {
545 BeginOp(B_PIC_SET_FONT_ROTATE);
546 Write<float>(rotation);
547 EndOp();
548 } catch (status_t& status) {
549 return status;
552 return B_OK;
556 status_t
557 PictureDataWriter::WriteSetFontEncoding(const int32& encoding)
559 try {
560 BeginOp(B_PIC_SET_FONT_ENCODING);
561 Write<int32>(encoding);
562 EndOp();
563 } catch (status_t& status) {
564 return status;
567 return B_OK;
571 status_t
572 PictureDataWriter::WriteSetFontFlags(const int32& flags)
574 try {
575 BeginOp(B_PIC_SET_FONT_FLAGS);
576 Write<int32>(flags);
577 EndOp();
578 } catch (status_t& status) {
579 return status;
582 return B_OK;
586 status_t
587 PictureDataWriter::WriteSetFontShear(const float& shear)
589 try {
590 BeginOp(B_PIC_SET_FONT_SHEAR);
591 Write<float>(shear);
592 EndOp();
593 } catch (status_t& status) {
594 return status;
597 return B_OK;
601 status_t
602 PictureDataWriter::WriteSetFontFace(const int32& face)
604 try {
605 BeginOp(B_PIC_SET_FONT_FACE);
606 Write<int32>(face);
607 EndOp();
608 } catch (status_t& status) {
609 return status;
612 return B_OK;
616 status_t
617 PictureDataWriter::WritePushState()
619 try {
620 BeginOp(B_PIC_PUSH_STATE);
621 EndOp();
622 } catch (status_t& status) {
623 return status;
626 return B_OK;
630 status_t
631 PictureDataWriter::WritePopState()
633 try {
634 BeginOp(B_PIC_POP_STATE);
635 EndOp();
636 } catch (status_t& status) {
637 return status;
640 return B_OK;
644 // private
645 void
646 PictureDataWriter::BeginOp(const int16& op)
648 if (fData == NULL)
649 THROW_ERROR(B_NO_INIT);
651 fStack.push(fData->Position());
652 fData->Write(&op, sizeof(op));
654 // Init the size of the opcode block to 0
655 int32 size = 0;
656 fData->Write(&size, sizeof(size));
660 void
661 PictureDataWriter::EndOp()
663 if (fData == NULL)
664 THROW_ERROR(B_NO_INIT);
666 off_t curPos = fData->Position();
667 off_t stackPos = fStack.top();
668 fStack.pop();
670 // The size of the op is calculated like this:
671 // current position on the stream minus the position on the stack,
672 // minus the space occupied by the op code itself (int16)
673 // and the space occupied by the size field (int32)
674 int32 size = curPos - stackPos - sizeof(int32) - sizeof(int16);
676 // Size was set to 0 in BeginOp()
677 // Now we overwrite it with the correct value
678 fData->Seek(stackPos + sizeof(int16), SEEK_SET);
679 fData->Write(&size, sizeof(size));
680 fData->Seek(curPos, SEEK_SET);
684 void
685 PictureDataWriter::WriteData(const void* data, size_t size)
687 ssize_t result = fData->Write(data, size);
688 if (result < 0)
689 THROW_ERROR(result);
691 if ((size_t)result != size)
692 THROW_ERROR(B_IO_ERROR);