btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / interface / PictureDataWriter.cpp
blob1d99c5e4bc8aebd9e636b91d4720d1ed47bc2c45
1 /*
2 * Copyright 2006-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stefano Ceccherini, stefano.ceccherini@gmail.com
7 * Julian Harnath, <julian.harnath@rwth-achen.de>
8 */
10 #include <PictureDataWriter.h>
12 #include <stdio.h>
13 #include <string.h>
15 #include <DataIO.h>
16 #include <Point.h>
17 #include <Rect.h>
18 #include <Region.h>
20 #include <PictureProtocol.h>
22 #define THROW_ERROR(error) throw (status_t)(error)
25 // TODO: Review writing of strings. AFAIK in the picture data format
26 // They are not supposed to be NULL terminated
27 // (at least, it's not mandatory) so we should write their size too.
28 PictureDataWriter::PictureDataWriter()
30 fData(NULL)
35 PictureDataWriter::PictureDataWriter(BPositionIO* data)
37 fData(data)
42 PictureDataWriter::~PictureDataWriter()
47 status_t
48 PictureDataWriter::SetTo(BPositionIO* data)
50 if (data == NULL)
51 return B_BAD_VALUE;
53 fData = data;
55 return B_OK;
59 status_t
60 PictureDataWriter::WriteSetOrigin(const BPoint& point)
62 try {
63 BeginOp(B_PIC_SET_ORIGIN);
64 Write<BPoint>(point);
65 EndOp();
66 } catch (status_t& status) {
67 return status;
70 return B_OK;
74 status_t
75 PictureDataWriter::WriteInvertRect(const BRect& rect)
77 try {
78 WriteSetDrawingMode(B_OP_INVERT);
80 BeginOp(B_PIC_FILL_RECT);
81 Write<BRect>(rect);
82 EndOp();
84 WriteSetDrawingMode(B_OP_COPY);
85 } catch (status_t& status) {
86 return status;
89 return B_OK;
93 status_t
94 PictureDataWriter::WriteSetDrawingMode(const drawing_mode& mode)
96 try {
97 BeginOp(B_PIC_SET_DRAWING_MODE);
98 Write<int16>((int16)mode);
99 EndOp();
100 } catch (status_t& status) {
101 return status;
104 return B_OK;
108 status_t
109 PictureDataWriter::WriteSetPenLocation(const BPoint& point)
111 try {
112 BeginOp(B_PIC_SET_PEN_LOCATION);
113 Write<BPoint>(point);
114 EndOp();
115 } catch (status_t& status) {
116 return status;
119 return B_OK;
123 status_t
124 PictureDataWriter::WriteSetPenSize(const float& penSize)
126 try {
127 BeginOp(B_PIC_SET_PEN_SIZE);
128 Write<float>(penSize);
129 EndOp();
130 } catch (status_t& status) {
131 return status;
134 return B_OK;
138 status_t
139 PictureDataWriter::WriteSetLineMode(const cap_mode& cap, const join_mode& join,
140 const float& miterLimit)
142 try {
143 BeginOp(B_PIC_SET_LINE_MODE);
144 Write<int16>((int16)cap);
145 Write<int16>((int16)join);
146 Write<float>(miterLimit);
147 EndOp();
148 } catch (status_t& status) {
149 return status;
152 return B_OK;
156 status_t
157 PictureDataWriter::WriteSetScale(const float& scale)
159 try {
160 BeginOp(B_PIC_SET_SCALE);
161 Write<float>(scale);
162 EndOp();
163 } catch (status_t& status) {
164 return status;
167 return B_OK;
171 status_t
172 PictureDataWriter::WriteSetTransform(BAffineTransform transform)
174 try {
175 BeginOp(B_PIC_SET_TRANSFORM);
176 Write<BAffineTransform>(transform);
177 EndOp();
178 } catch (status_t& status) {
179 return status;
182 return B_OK;
186 status_t
187 PictureDataWriter::WriteTranslateBy(double x, double y)
189 try {
190 BeginOp(B_PIC_AFFINE_TRANSLATE);
191 Write<double>(x);
192 Write<double>(y);
193 EndOp();
194 } catch (status_t& status) {
195 return status;
198 return B_OK;
202 status_t
203 PictureDataWriter::WriteScaleBy(double x, double y)
205 try {
206 BeginOp(B_PIC_AFFINE_SCALE);
207 Write<double>(x);
208 Write<double>(y);
209 EndOp();
210 } catch (status_t& status) {
211 return status;
214 return B_OK;
218 status_t
219 PictureDataWriter::WriteRotateBy(double angleRadians)
221 try {
222 BeginOp(B_PIC_AFFINE_ROTATE);
223 Write<double>(angleRadians);
224 EndOp();
225 } catch (status_t& status) {
226 return status;
229 return B_OK;
233 status_t
234 PictureDataWriter::WriteSetPattern(const ::pattern& pattern)
236 try {
237 BeginOp(B_PIC_SET_STIPLE_PATTERN);
238 Write< ::pattern>(pattern);
239 EndOp();
240 } catch (status_t& status) {
241 return status;
244 return B_OK;
248 status_t
249 PictureDataWriter::WriteClipToPicture(int32 pictureToken,
250 const BPoint& origin, bool inverse)
252 // TODO: I don't know if it's compatible with R5's BPicture version
253 try {
254 BeginOp(B_PIC_CLIP_TO_PICTURE);
255 Write<int32>(pictureToken);
256 Write<BPoint>(origin);
257 Write<bool>(inverse);
258 EndOp();
259 } catch (status_t& status) {
260 return status;
263 return B_OK;
267 status_t
268 PictureDataWriter::WriteSetClipping(const BRegion& region)
270 // TODO: I don't know if it's compatible with R5's BPicture version
271 try {
272 const int32 numRects = region.CountRects();
273 if (numRects > 0 && region.Frame().IsValid()) {
274 BeginOp(B_PIC_SET_CLIPPING_RECTS);
275 Write<uint32>(numRects);
276 for (int32 i = 0; i < numRects; i++)
277 Write<BRect>(region.RectAt(i));
279 EndOp();
280 } else
281 WriteClearClipping();
282 } catch (status_t& status) {
283 return status;
286 return B_OK;
290 status_t
291 PictureDataWriter::WriteClearClipping()
293 try {
294 BeginOp(B_PIC_CLEAR_CLIPPING_RECTS);
295 EndOp();
296 } catch (status_t& status) {
297 return status;
300 return B_OK;
304 status_t
305 PictureDataWriter::WriteSetHighColor(const rgb_color& color)
307 try {
308 BeginOp(B_PIC_SET_FORE_COLOR);
309 Write<rgb_color>(color);
310 EndOp();
311 } catch (status_t& status) {
312 return status;
315 return B_OK;
319 status_t
320 PictureDataWriter::WriteSetLowColor(const rgb_color& color)
322 try {
323 BeginOp(B_PIC_SET_BACK_COLOR);
324 Write<rgb_color>(color);
325 EndOp();
326 } catch (status_t& status) {
327 return status;
330 return B_OK;
334 status_t
335 PictureDataWriter::WriteDrawRect(const BRect& rect, const bool& fill)
337 try {
338 BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT);
339 Write<BRect>(rect);
340 EndOp();
341 } catch (status_t& status) {
342 return status;
345 return B_OK;
349 status_t
350 PictureDataWriter::WriteDrawRoundRect(const BRect& rect, const BPoint& radius,
351 const bool& fill)
353 try {
354 BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT);
355 Write<BRect>(rect);
356 Write<BPoint>(radius);
357 EndOp();
358 } catch (status_t& status) {
359 return status;
362 return B_OK;
366 status_t
367 PictureDataWriter::WriteDrawEllipse(const BRect& rect, const bool& fill)
369 try {
370 BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE);
371 Write<BRect>(rect);
372 EndOp();
373 } catch (status_t& status) {
374 return status;
377 return B_OK;
381 status_t
382 PictureDataWriter::WriteDrawArc(const BPoint& center, const BPoint& radius,
383 const float& startTheta, const float& arcTheta, const bool& fill)
385 try {
386 BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC);
387 Write<BPoint>(center);
388 Write<BPoint>(radius);
389 Write<float>(startTheta);
390 Write<float>(arcTheta);
391 EndOp();
392 } catch (status_t& status) {
393 return status;
396 return B_OK;
400 status_t
401 PictureDataWriter::WriteDrawPolygon(const int32& numPoints, BPoint* points,
402 const bool& isClosed, const bool& fill)
404 try {
405 BeginOp(fill ? B_PIC_FILL_POLYGON : B_PIC_STROKE_POLYGON);
406 Write<int32>(numPoints);
407 for (int32 i = 0; i < numPoints; i++)
408 Write<BPoint>(points[i]);
410 if (!fill)
411 Write<uint8>((uint8)isClosed);
413 EndOp();
414 } catch (status_t& status) {
415 return status;
418 return B_OK;
422 status_t
423 PictureDataWriter::WriteDrawBezier(const BPoint points[4], const bool& fill)
425 try {
426 BeginOp(fill ? B_PIC_FILL_BEZIER : B_PIC_STROKE_BEZIER);
427 for (int32 i = 0; i < 4; i++)
428 Write<BPoint>(points[i]);
430 EndOp();
431 } catch (status_t& status) {
432 return status;
435 return B_OK;
439 status_t
440 PictureDataWriter::WriteStrokeLine(const BPoint& start, const BPoint& end)
442 try {
443 BeginOp(B_PIC_STROKE_LINE);
444 Write<BPoint>(start);
445 Write<BPoint>(end);
446 EndOp();
447 } catch (status_t& status) {
448 return status;
451 return B_OK;
455 status_t
456 PictureDataWriter::WriteDrawString(const BPoint& where, const char* string,
457 const int32& length, const escapement_delta& escapement)
459 try {
460 BeginOp(B_PIC_SET_PEN_LOCATION);
461 Write<BPoint>(where);
462 EndOp();
464 BeginOp(B_PIC_DRAW_STRING);
465 Write<float>(escapement.space);
466 Write<float>(escapement.nonspace);
467 //WriteData(string, length + 1);
468 // TODO: is string 0 terminated? why is length given?
469 WriteData(string, length);
470 Write<uint8>(0);
471 EndOp();
472 } catch (status_t& status) {
473 return status;
476 return B_OK;
480 status_t
481 PictureDataWriter::WriteDrawShape(const int32& opCount, const void* opList,
482 const int32& ptCount, const void* ptList, const bool& fill)
484 try {
485 BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE);
486 Write<int32>(opCount);
487 Write<int32>(ptCount);
488 WriteData(opList, opCount * sizeof(uint32));
489 WriteData(ptList, ptCount * sizeof(BPoint));
490 EndOp();
491 } catch (status_t& status) {
492 return status;
495 return B_OK;
499 status_t
500 PictureDataWriter::WriteDrawBitmap(const BRect& srcRect, const BRect& dstRect,
501 const int32& width, const int32& height, const int32& bytesPerRow,
502 const int32& colorSpace, const int32& flags, const void* data,
503 const int32& length)
505 if (length != height * bytesPerRow)
506 debugger("PictureDataWriter::WriteDrawBitmap: invalid length");
507 try {
508 BeginOp(B_PIC_DRAW_PIXELS);
509 Write<BRect>(srcRect);
510 Write<BRect>(dstRect);
511 Write<int32>(width);
512 Write<int32>(height);
513 Write<int32>(bytesPerRow);
514 Write<int32>(colorSpace);
515 Write<int32>(flags);
516 WriteData(data, length);
517 EndOp();
518 } catch (status_t& status) {
519 return status;
522 return B_OK;
526 status_t
527 PictureDataWriter::WriteDrawPicture(const BPoint& where, const int32& token)
529 // TODO: I'm not sure about this function. I think we need
530 // to attach the picture data too.
531 // The token won't be sufficient in many cases (for example, when
532 // we archive/flatten the picture.
533 try {
534 BeginOp(B_PIC_DRAW_PICTURE);
535 Write<BPoint>(where);
536 Write<int32>(token);
537 EndOp();
538 } catch (status_t& status) {
539 return status;
542 return B_OK;
546 status_t
547 PictureDataWriter::WriteSetFontFamily(const font_family family)
549 try {
550 BeginOp(B_PIC_SET_FONT_FAMILY);
551 WriteData(family, strlen(family));
552 Write<uint8>(0);
553 EndOp();
554 } catch (status_t& status) {
555 return status;
558 return B_OK;
562 status_t
563 PictureDataWriter::WriteSetFontStyle(const font_style style)
565 try {
566 BeginOp(B_PIC_SET_FONT_STYLE);
567 WriteData(style, strlen(style));
568 Write<uint8>(0);
569 EndOp();
570 } catch (status_t& status) {
571 return status;
574 return B_OK;
578 status_t
579 PictureDataWriter::WriteSetFontSpacing(const int32& spacing)
581 try {
582 BeginOp(B_PIC_SET_FONT_SPACING);
583 Write<int32>(spacing);
584 EndOp();
585 } catch (status_t& status) {
586 return status;
589 return B_OK;
593 status_t
594 PictureDataWriter::WriteSetFontSize(const float& size)
596 try {
597 BeginOp(B_PIC_SET_FONT_SIZE);
598 Write<float>(size);
599 EndOp();
600 } catch (status_t& status) {
601 return status;
604 return B_OK;
608 status_t
609 PictureDataWriter::WriteSetFontRotation(const float& rotation)
611 try {
612 BeginOp(B_PIC_SET_FONT_ROTATE);
613 Write<float>(rotation);
614 EndOp();
615 } catch (status_t& status) {
616 return status;
619 return B_OK;
623 status_t
624 PictureDataWriter::WriteSetFontEncoding(const int32& encoding)
626 try {
627 BeginOp(B_PIC_SET_FONT_ENCODING);
628 Write<int32>(encoding);
629 EndOp();
630 } catch (status_t& status) {
631 return status;
634 return B_OK;
638 status_t
639 PictureDataWriter::WriteSetFontFlags(const int32& flags)
641 try {
642 BeginOp(B_PIC_SET_FONT_FLAGS);
643 Write<int32>(flags);
644 EndOp();
645 } catch (status_t& status) {
646 return status;
649 return B_OK;
653 status_t
654 PictureDataWriter::WriteSetFontShear(const float& shear)
656 try {
657 BeginOp(B_PIC_SET_FONT_SHEAR);
658 Write<float>(shear);
659 EndOp();
660 } catch (status_t& status) {
661 return status;
664 return B_OK;
668 status_t
669 PictureDataWriter::WriteSetFontFace(const int32& face)
671 try {
672 BeginOp(B_PIC_SET_FONT_FACE);
673 Write<int32>(face);
674 EndOp();
675 } catch (status_t& status) {
676 return status;
679 return B_OK;
683 status_t
684 PictureDataWriter::WritePushState()
686 try {
687 BeginOp(B_PIC_PUSH_STATE);
688 EndOp();
689 } catch (status_t& status) {
690 return status;
693 return B_OK;
697 status_t
698 PictureDataWriter::WritePopState()
700 try {
701 BeginOp(B_PIC_POP_STATE);
702 EndOp();
703 } catch (status_t& status) {
704 return status;
707 return B_OK;
711 status_t
712 PictureDataWriter::WriteBlendLayer(Layer* layer)
714 try {
715 BeginOp(B_PIC_BLEND_LAYER);
716 Write<Layer*>(layer);
717 EndOp();
718 } catch (status_t& status) {
719 return status;
722 return B_OK;
726 status_t
727 PictureDataWriter::WriteClipToRect(const BRect& rect, bool inverse)
729 try {
730 BeginOp(B_PIC_CLIP_TO_RECT);
731 Write<bool>(inverse);
732 Write<BRect>(rect);
733 EndOp();
734 } catch (status_t& status) {
735 return status;
738 return B_OK;
742 status_t
743 PictureDataWriter::WriteClipToShape(int32 opCount, const void* opList,
744 int32 ptCount, const void* ptList, bool inverse)
746 try {
747 BeginOp(B_PIC_CLIP_TO_SHAPE);
748 Write<bool>(inverse);
749 Write<int32>(opCount);
750 Write<int32>(ptCount);
751 WriteData(opList, opCount * sizeof(uint32));
752 WriteData(ptList, ptCount * sizeof(BPoint));
753 EndOp();
754 } catch (status_t& status) {
755 return status;
758 return B_OK;
762 // private
763 void
764 PictureDataWriter::BeginOp(const int16& op)
766 if (fData == NULL)
767 THROW_ERROR(B_NO_INIT);
769 fStack.push(fData->Position());
770 fData->Write(&op, sizeof(op));
772 // Init the size of the opcode block to 0
773 int32 size = 0;
774 fData->Write(&size, sizeof(size));
778 void
779 PictureDataWriter::EndOp()
781 if (fData == NULL)
782 THROW_ERROR(B_NO_INIT);
784 off_t curPos = fData->Position();
785 off_t stackPos = fStack.top();
786 fStack.pop();
788 // The size of the op is calculated like this:
789 // current position on the stream minus the position on the stack,
790 // minus the space occupied by the op code itself (int16)
791 // and the space occupied by the size field (int32)
792 int32 size = curPos - stackPos - sizeof(int32) - sizeof(int16);
794 // Size was set to 0 in BeginOp()
795 // Now we overwrite it with the correct value
796 fData->Seek(stackPos + sizeof(int16), SEEK_SET);
797 fData->Write(&size, sizeof(size));
798 fData->Seek(curPos, SEEK_SET);
802 void
803 PictureDataWriter::WriteData(const void* data, size_t size)
805 ssize_t result = fData->Write(data, size);
806 if (result < 0)
807 THROW_ERROR(result);
809 if ((size_t)result != size)
810 THROW_ERROR(B_IO_ERROR);