2 * Copyright 2001-2007, Haiku Inc.
3 * Distributed under the terms of the MIT License.
6 * Marc Flerackers (mflerackers@androme.be)
7 * Stefano Ceccherini (stefano.ceccherini@gmail.com)
8 * Marcus Overhagen (marcus@overhagen.de)
11 /** PicturePlayer is used to play picture data. */
13 #include <PicturePlayer.h>
19 #include <AffineTransform.h>
20 #include <PictureProtocol.h>
24 using BPrivate::PicturePlayer
;
27 struct adapter_context
{
29 void** function_table
;
40 move_pen_by(void* _context
, const BPoint
& delta
)
42 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
43 ((void (*)(void*, BPoint
))context
->function_table
[1])(context
->user_data
,
49 stroke_line(void* _context
, const BPoint
& start
, const BPoint
& end
)
51 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
52 ((void (*)(void*, BPoint
, BPoint
))context
->function_table
[2])(
53 context
->user_data
, start
, end
);
58 draw_rect(void* _context
, const BRect
& rect
, bool fill
)
60 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
61 ((void (*)(void*, BRect
))context
->function_table
[fill
? 4 : 3])(
62 context
->user_data
, rect
);
67 draw_round_rect(void* _context
, const BRect
& rect
, const BPoint
& radii
,
70 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
71 ((void (*)(void*, BRect
, BPoint
))context
->function_table
[fill
? 6 : 5])(
72 context
->user_data
, rect
, radii
);
77 draw_bezier(void* _context
, size_t numPoints
, const BPoint _points
[], bool fill
)
79 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
83 BPoint points
[4] = { _points
[0], _points
[1], _points
[2], _points
[3] };
84 ((void (*)(void*, BPoint
*))context
->function_table
[fill
? 8 : 7])(
85 context
->user_data
, points
);
90 draw_arc(void* _context
, const BPoint
& center
, const BPoint
& radii
,
91 float startTheta
, float arcTheta
, bool fill
)
93 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
94 ((void (*)(void*, BPoint
, BPoint
, float, float))
95 context
->function_table
[fill
? 10 : 9])(context
->user_data
, center
,
96 radii
, startTheta
, arcTheta
);
101 draw_ellipse(void* _context
, const BRect
& rect
, bool fill
)
103 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
104 BPoint
radii((rect
.Width() + 1) / 2.0f
, (rect
.Height() + 1) / 2.0f
);
105 BPoint center
= rect
.LeftTop() + radii
;
106 ((void (*)(void*, BPoint
, BPoint
))
107 context
->function_table
[fill
? 12 : 11])(context
->user_data
, center
,
113 draw_polygon(void* _context
, size_t numPoints
, const BPoint _points
[],
114 bool isClosed
, bool fill
)
116 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
118 // This is rather ugly but works for such a trivial class.
119 const size_t kMaxStackCount
= 200;
120 char stackData
[kMaxStackCount
* sizeof(BPoint
)];
121 BPoint
* points
= (BPoint
*)stackData
;
122 if (numPoints
> kMaxStackCount
) {
123 points
= (BPoint
*)malloc(numPoints
* sizeof(BPoint
));
128 memcpy(points
, _points
, numPoints
* sizeof(BPoint
));
130 ((void (*)(void*, int32
, BPoint
*, bool))
131 context
->function_table
[fill
? 14 : 13])(context
->user_data
, numPoints
,
134 if (numPoints
> kMaxStackCount
)
140 draw_shape(void* _context
, const BShape
& shape
, bool fill
)
142 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
143 ((void (*)(void*, BShape
))context
->function_table
[fill
? 16 : 15])(
144 context
->user_data
, shape
);
149 draw_string(void* _context
, const char* _string
, size_t length
,
150 float deltaSpace
, float deltaNonSpace
)
152 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
153 char* string
= strndup(_string
, length
);
155 ((void (*)(void*, char*, float, float))
156 context
->function_table
[17])(context
->user_data
, string
, deltaSpace
,
164 draw_pixels(void* _context
, const BRect
& src
, const BRect
& dest
, uint32 width
,
165 uint32 height
, size_t bytesPerRow
, color_space pixelFormat
, uint32 options
,
166 const void* _data
, size_t length
)
168 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
169 void* data
= malloc(length
);
173 memcpy(data
, _data
, length
);
175 ((void (*)(void*, BRect
, BRect
, int32
, int32
, int32
, int32
, int32
, void*))
176 context
->function_table
[18])(context
->user_data
, src
, dest
, width
,
177 height
, bytesPerRow
, pixelFormat
, options
, data
);
184 draw_picture(void* _context
, const BPoint
& where
, int32 token
)
186 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
187 ((void (*)(void*, BPoint
, int32
))context
->function_table
[19])(
188 context
->user_data
, where
, token
);
193 set_clipping_rects(void* _context
, size_t numRects
, const BRect _rects
[])
195 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
197 // This is rather ugly but works for such a trivial class.
198 const size_t kMaxStackCount
= 100;
199 char stackData
[kMaxStackCount
* sizeof(BRect
)];
200 BRect
* rects
= (BRect
*)stackData
;
201 if (numRects
> kMaxStackCount
) {
202 rects
= (BRect
*)malloc(numRects
* sizeof(BRect
));
207 memcpy(rects
, _rects
, numRects
* sizeof(BRect
));
209 ((void (*)(void*, BRect
*, uint32
))context
->function_table
[20])(
210 context
->user_data
, rects
, numRects
);
212 if (numRects
> kMaxStackCount
)
218 clip_to_picture(void* _context
, int32 token
, const BPoint
& origin
,
221 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
222 ((void (*)(void*, int32
, BPoint
, bool))context
->function_table
[21])(
223 context
->user_data
, token
, origin
, clipToInverse
);
228 push_state(void* _context
)
230 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
231 ((void (*)(void*))context
->function_table
[22])(context
->user_data
);
236 pop_state(void* _context
)
238 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
239 ((void (*)(void*))context
->function_table
[23])(context
->user_data
);
244 enter_state_change(void* _context
)
246 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
247 ((void (*)(void*))context
->function_table
[24])(context
->user_data
);
252 exit_state_change(void* _context
)
254 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
255 ((void (*)(void*))context
->function_table
[25])(context
->user_data
);
260 enter_font_state(void* _context
)
262 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
263 ((void (*)(void*))context
->function_table
[26])(context
->user_data
);
268 exit_font_state(void* _context
)
270 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
271 ((void (*)(void*))context
->function_table
[27])(context
->user_data
);
276 set_origin(void* _context
, const BPoint
& origin
)
278 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
279 ((void (*)(void*, BPoint
))context
->function_table
[28])(context
->user_data
,
285 set_pen_location(void* _context
, const BPoint
& penLocation
)
287 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
288 ((void (*)(void*, BPoint
))context
->function_table
[29])(context
->user_data
,
294 set_drawing_mode(void* _context
, drawing_mode mode
)
296 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
297 ((void (*)(void*, drawing_mode
))context
->function_table
[30])(
298 context
->user_data
, mode
);
303 set_line_mode(void* _context
, cap_mode capMode
, join_mode joinMode
,
306 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
307 ((void (*)(void*, cap_mode
, join_mode
, float))context
->function_table
[31])(
308 context
->user_data
, capMode
, joinMode
, miterLimit
);
313 set_pen_size(void* _context
, float size
)
315 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
316 ((void (*)(void*, float))context
->function_table
[32])(context
->user_data
,
322 set_fore_color(void* _context
, const rgb_color
& color
)
324 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
325 ((void (*)(void*, rgb_color
))context
->function_table
[33])(
326 context
->user_data
, color
);
331 set_back_color(void* _context
, const rgb_color
& color
)
333 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
334 ((void (*)(void*, rgb_color
))context
->function_table
[34])(
335 context
->user_data
, color
);
340 set_stipple_pattern(void* _context
, const pattern
& stipplePattern
)
342 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
343 ((void (*)(void*, pattern
))context
->function_table
[35])(context
->user_data
,
349 set_scale(void* _context
, float scale
)
351 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
352 ((void (*)(void*, float))context
->function_table
[36])(context
->user_data
,
358 set_font_family(void* _context
, const char* _family
, size_t length
)
360 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
361 char* family
= strndup(_family
, length
);
363 ((void (*)(void*, char*))context
->function_table
[37])(context
->user_data
,
371 set_font_style(void* _context
, const char* _style
, size_t length
)
373 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
374 char* style
= strndup(_style
, length
);
376 ((void (*)(void*, char*))context
->function_table
[38])(context
->user_data
,
384 set_font_spacing(void* _context
, uint8 spacing
)
386 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
387 ((void (*)(void*, int32
))context
->function_table
[39])(context
->user_data
,
393 set_font_size(void* _context
, float size
)
395 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
396 ((void (*)(void*, float))context
->function_table
[40])(context
->user_data
,
402 set_font_rotation(void* _context
, float rotation
)
404 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
405 ((void (*)(void*, float))context
->function_table
[41])(context
->user_data
,
411 set_font_encoding(void* _context
, uint8 encoding
)
413 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
414 ((void (*)(void*, int32
))context
->function_table
[42])(context
->user_data
,
420 set_font_flags(void* _context
, uint32 flags
)
422 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
423 ((void (*)(void*, int32
))context
->function_table
[43])(context
->user_data
,
429 set_font_shear(void* _context
, float shear
)
431 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
432 ((void (*)(void*, float))context
->function_table
[44])(context
->user_data
,
438 set_font_face(void* _context
, uint16 face
)
440 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
441 ((void (*)(void*, int32
))context
->function_table
[46])(context
->user_data
,
447 set_blending_mode(void* _context
, source_alpha alphaSrcMode
,
448 alpha_function alphaFncMode
)
450 adapter_context
* context
= reinterpret_cast<adapter_context
*>(_context
);
451 ((void (*)(void*, source_alpha
, alpha_function
))
452 context
->function_table
[47])(context
->user_data
, alphaSrcMode
,
459 PictureOpToString(int op
)
461 #define RETURN_STRING(x) case x: return #x
464 RETURN_STRING(B_PIC_MOVE_PEN_BY
);
465 RETURN_STRING(B_PIC_STROKE_LINE
);
466 RETURN_STRING(B_PIC_STROKE_RECT
);
467 RETURN_STRING(B_PIC_FILL_RECT
);
468 RETURN_STRING(B_PIC_STROKE_ROUND_RECT
);
469 RETURN_STRING(B_PIC_FILL_ROUND_RECT
);
470 RETURN_STRING(B_PIC_STROKE_BEZIER
);
471 RETURN_STRING(B_PIC_FILL_BEZIER
);
472 RETURN_STRING(B_PIC_STROKE_POLYGON
);
473 RETURN_STRING(B_PIC_FILL_POLYGON
);
474 RETURN_STRING(B_PIC_STROKE_SHAPE
);
475 RETURN_STRING(B_PIC_FILL_SHAPE
);
476 RETURN_STRING(B_PIC_DRAW_STRING
);
477 RETURN_STRING(B_PIC_DRAW_PIXELS
);
478 RETURN_STRING(B_PIC_DRAW_PICTURE
);
479 RETURN_STRING(B_PIC_STROKE_ARC
);
480 RETURN_STRING(B_PIC_FILL_ARC
);
481 RETURN_STRING(B_PIC_STROKE_ELLIPSE
);
482 RETURN_STRING(B_PIC_FILL_ELLIPSE
);
484 RETURN_STRING(B_PIC_ENTER_STATE_CHANGE
);
485 RETURN_STRING(B_PIC_SET_CLIPPING_RECTS
);
486 RETURN_STRING(B_PIC_CLIP_TO_PICTURE
);
487 RETURN_STRING(B_PIC_PUSH_STATE
);
488 RETURN_STRING(B_PIC_POP_STATE
);
489 RETURN_STRING(B_PIC_CLEAR_CLIPPING_RECTS
);
491 RETURN_STRING(B_PIC_SET_ORIGIN
);
492 RETURN_STRING(B_PIC_SET_PEN_LOCATION
);
493 RETURN_STRING(B_PIC_SET_DRAWING_MODE
);
494 RETURN_STRING(B_PIC_SET_LINE_MODE
);
495 RETURN_STRING(B_PIC_SET_PEN_SIZE
);
496 RETURN_STRING(B_PIC_SET_SCALE
);
497 RETURN_STRING(B_PIC_SET_TRANSFORM
);
498 RETURN_STRING(B_PIC_SET_FORE_COLOR
);
499 RETURN_STRING(B_PIC_SET_BACK_COLOR
);
500 RETURN_STRING(B_PIC_SET_STIPLE_PATTERN
);
501 RETURN_STRING(B_PIC_ENTER_FONT_STATE
);
502 RETURN_STRING(B_PIC_SET_BLENDING_MODE
);
503 RETURN_STRING(B_PIC_SET_FONT_FAMILY
);
504 RETURN_STRING(B_PIC_SET_FONT_STYLE
);
505 RETURN_STRING(B_PIC_SET_FONT_SPACING
);
506 RETURN_STRING(B_PIC_SET_FONT_ENCODING
);
507 RETURN_STRING(B_PIC_SET_FONT_FLAGS
);
508 RETURN_STRING(B_PIC_SET_FONT_SIZE
);
509 RETURN_STRING(B_PIC_SET_FONT_ROTATE
);
510 RETURN_STRING(B_PIC_SET_FONT_SHEAR
);
511 RETURN_STRING(B_PIC_SET_FONT_BPP
);
512 RETURN_STRING(B_PIC_SET_FONT_FACE
);
513 default: return "Unknown op";
520 PicturePlayer::PicturePlayer(const void *data
, size_t size
, BList
*pictures
)
528 PicturePlayer::~PicturePlayer()
534 PicturePlayer::Play(void** callBackTable
, int32 tableEntries
, void* userData
)
536 const BPrivate::picture_player_callbacks kAdapterCallbacks
= {
578 // We don't check if the functions in the table are NULL, but we
579 // check the tableEntries to see if the table is big enough.
580 // If an application supplies the wrong size or an invalid pointer,
581 // it's its own fault.
583 // If the caller supplied a function table smaller than needed,
584 // we use our dummy table, and copy the supported ops from the supplied one.
585 void *dummyTable
[kOpsTableSize
];
587 adapter_context adapterContext
;
588 adapterContext
.user_data
= userData
;
589 adapterContext
.function_table
= callBackTable
;
591 if ((size_t)tableEntries
< kOpsTableSize
) {
592 memcpy(dummyTable
, callBackTable
, tableEntries
* sizeof(void*));
593 for (size_t i
= (size_t)tableEntries
; i
< kOpsTableSize
; i
++)
594 dummyTable
[i
] = (void*)nop
;
596 adapterContext
.function_table
= dummyTable
;
599 return _Play(kAdapterCallbacks
, &adapterContext
, fData
, fSize
, 0);
604 PicturePlayer::Play(const picture_player_callbacks
& callbacks
,
605 size_t callbacksSize
, void* userData
)
607 return _Play(callbacks
, userData
, fData
, fSize
, 0);
613 DataReader(const void* buffer
, size_t length
)
615 fBuffer((const uint8
*)buffer
),
628 Get(const T
*& typed
, size_t count
= 1)
630 if (fRemaining
< sizeof(T
) * count
)
633 typed
= reinterpret_cast<const T
*>(fBuffer
);
634 fRemaining
-= sizeof(T
) * count
;
635 fBuffer
+= sizeof(T
) * count
;
641 GetRemaining(const T
*& buffer
, size_t& size
)
646 buffer
= reinterpret_cast<const T
*>(fBuffer
);
653 const uint8
* fBuffer
;
658 struct picture_data_entry_header
{
665 PicturePlayer::_Play(const picture_player_callbacks
& callbacks
, void* userData
,
666 const void* buffer
, size_t length
, uint16 parentOp
)
669 printf("Start rendering %sBPicture...\n", parentOp
!= 0 ? "sub " : "");
670 bigtime_t startTime
= system_time();
674 DataReader
pictureReader(buffer
, length
);
676 while (pictureReader
.Remaining() > 0) {
677 const picture_data_entry_header
* header
;
678 const uint8
* opData
= NULL
;
679 if (!pictureReader
.Get(header
)
680 || !pictureReader
.Get(opData
, header
->size
)) {
684 DataReader
reader(opData
, header
->size
);
686 // Disallow ops that don't fit the parent.
689 // No parent op, no restrictions.
692 case B_PIC_ENTER_STATE_CHANGE
:
693 if (header
->op
<= B_PIC_ENTER_STATE_CHANGE
694 || header
->op
> B_PIC_SET_TRANSFORM
) {
699 case B_PIC_ENTER_FONT_STATE
:
700 if (header
->op
< B_PIC_SET_FONT_FAMILY
701 || header
->op
> B_PIC_SET_FONT_FACE
) {
711 bigtime_t startOpTime
= system_time();
712 printf("Op %s ", PictureOpToString(header
->op
));
714 switch (header
->op
) {
715 case B_PIC_MOVE_PEN_BY
:
718 if (callbacks
.move_pen_by
== NULL
|| !reader
.Get(where
))
721 callbacks
.move_pen_by(userData
, *where
);
725 case B_PIC_STROKE_LINE
:
729 if (callbacks
.stroke_line
== NULL
|| !reader
.Get(start
)
730 || !reader
.Get(end
)) {
734 callbacks
.stroke_line(userData
, *start
, *end
);
738 case B_PIC_STROKE_RECT
:
739 case B_PIC_FILL_RECT
:
742 if (callbacks
.draw_rect
== NULL
|| !reader
.Get(rect
))
745 callbacks
.draw_rect(userData
, *rect
,
746 header
->op
== B_PIC_FILL_RECT
);
750 case B_PIC_STROKE_ROUND_RECT
:
751 case B_PIC_FILL_ROUND_RECT
:
755 if (callbacks
.draw_round_rect
== NULL
|| !reader
.Get(rect
)
756 || !reader
.Get(radii
)) {
760 callbacks
.draw_round_rect(userData
, *rect
, *radii
,
761 header
->op
== B_PIC_FILL_ROUND_RECT
);
765 case B_PIC_STROKE_BEZIER
:
766 case B_PIC_FILL_BEZIER
:
768 const size_t kNumControlPoints
= 4;
769 const BPoint
* controlPoints
;
770 if (callbacks
.draw_bezier
== NULL
771 || !reader
.Get(controlPoints
, kNumControlPoints
)) {
775 callbacks
.draw_bezier(userData
, kNumControlPoints
,
776 controlPoints
, header
->op
== B_PIC_FILL_BEZIER
);
780 case B_PIC_STROKE_ARC
:
783 const BPoint
* center
;
785 const float* startTheta
;
786 const float* arcTheta
;
787 if (callbacks
.draw_arc
== NULL
|| !reader
.Get(center
)
788 || !reader
.Get(radii
) || !reader
.Get(startTheta
)
789 || !reader
.Get(arcTheta
)) {
793 callbacks
.draw_arc(userData
, *center
, *radii
, *startTheta
,
794 *arcTheta
, header
->op
== B_PIC_FILL_ARC
);
798 case B_PIC_STROKE_ELLIPSE
:
799 case B_PIC_FILL_ELLIPSE
:
802 if (callbacks
.draw_ellipse
== NULL
|| !reader
.Get(rect
))
805 callbacks
.draw_ellipse(userData
, *rect
,
806 header
->op
== B_PIC_FILL_ELLIPSE
);
810 case B_PIC_STROKE_POLYGON
:
811 case B_PIC_FILL_POLYGON
:
813 const uint32
* numPoints
;
814 const BPoint
* points
;
815 if (callbacks
.draw_polygon
== NULL
|| !reader
.Get(numPoints
)
816 || !reader
.Get(points
, *numPoints
)) {
820 bool isClosed
= true;
821 const bool* closedPointer
;
822 if (header
->op
!= B_PIC_FILL_POLYGON
) {
823 if (!reader
.Get(closedPointer
))
826 isClosed
= *closedPointer
;
829 callbacks
.draw_polygon(userData
, *numPoints
, points
, isClosed
,
830 header
->op
== B_PIC_FILL_POLYGON
);
834 case B_PIC_STROKE_SHAPE
:
835 case B_PIC_FILL_SHAPE
:
837 const uint32
* opCount
;
838 const uint32
* pointCount
;
839 const uint32
* opList
;
840 const BPoint
* pointList
;
841 if (callbacks
.draw_shape
== NULL
|| !reader
.Get(opCount
)
842 || !reader
.Get(pointCount
) || !reader
.Get(opList
, *opCount
)
843 || !reader
.Get(pointList
, *pointCount
)) {
847 // TODO: remove BShape data copying
849 shape
.SetData(*opCount
, *pointCount
, opList
, pointList
);
851 callbacks
.draw_shape(userData
, shape
,
852 header
->op
== B_PIC_FILL_SHAPE
);
856 case B_PIC_DRAW_STRING
:
858 const float* escapementSpace
;
859 const float* escapementNonSpace
;
862 if (callbacks
.draw_string
== NULL
863 || !reader
.Get(escapementSpace
)
864 || !reader
.Get(escapementNonSpace
)
865 || !reader
.GetRemaining(string
, length
)) {
869 callbacks
.draw_string(userData
, string
, length
,
870 *escapementSpace
, *escapementNonSpace
);
874 case B_PIC_DRAW_PIXELS
:
876 const BRect
* sourceRect
;
877 const BRect
* destinationRect
;
879 const uint32
* height
;
880 const uint32
* bytesPerRow
;
881 const uint32
* colorSpace
;
885 if (callbacks
.draw_pixels
== NULL
|| !reader
.Get(sourceRect
)
886 || !reader
.Get(destinationRect
) || !reader
.Get(width
)
887 || !reader
.Get(height
) || !reader
.Get(bytesPerRow
)
888 || !reader
.Get(colorSpace
) || !reader
.Get(flags
)
889 || !reader
.GetRemaining(data
, length
)) {
893 callbacks
.draw_pixels(userData
, *sourceRect
, *destinationRect
,
894 *width
, *height
, *bytesPerRow
, (color_space
)*colorSpace
,
895 *flags
, data
, length
);
899 case B_PIC_DRAW_PICTURE
:
903 if (callbacks
.draw_picture
== NULL
|| !reader
.Get(where
)
904 || !reader
.Get(token
)) {
908 callbacks
.draw_picture(userData
, *where
, *token
);
912 case B_PIC_SET_CLIPPING_RECTS
:
914 const uint32
* numRects
;
916 if (callbacks
.set_clipping_rects
== NULL
917 || !reader
.Get(numRects
) || !reader
.Get(rects
, *numRects
)) {
921 callbacks
.set_clipping_rects(userData
, *numRects
, rects
);
925 case B_PIC_CLEAR_CLIPPING_RECTS
:
927 if (callbacks
.set_clipping_rects
== NULL
)
930 callbacks
.set_clipping_rects(userData
, 0, NULL
);
934 case B_PIC_CLIP_TO_PICTURE
:
939 if (callbacks
.clip_to_picture
== NULL
|| !reader
.Get(token
)
940 || !reader
.Get(where
) || !reader
.Get(inverse
))
943 callbacks
.clip_to_picture(userData
, *token
, *where
, *inverse
);
947 case B_PIC_PUSH_STATE
:
949 if (callbacks
.push_state
== NULL
)
952 callbacks
.push_state(userData
);
956 case B_PIC_POP_STATE
:
958 if (callbacks
.pop_state
== NULL
)
961 callbacks
.pop_state(userData
);
965 case B_PIC_ENTER_STATE_CHANGE
:
966 case B_PIC_ENTER_FONT_STATE
:
970 if (!reader
.GetRemaining(data
, length
))
973 if (header
->op
== B_PIC_ENTER_STATE_CHANGE
) {
974 if (callbacks
.enter_state_change
!= NULL
)
975 callbacks
.enter_state_change(userData
);
976 } else if (callbacks
.enter_font_state
!= NULL
)
977 callbacks
.enter_font_state(userData
);
979 status_t result
= _Play(callbacks
, userData
, data
, length
,
984 if (header
->op
== B_PIC_ENTER_STATE_CHANGE
) {
985 if (callbacks
.exit_state_change
!= NULL
)
986 callbacks
.exit_state_change(userData
);
987 } else if (callbacks
.exit_font_state
!= NULL
)
988 callbacks
.exit_font_state(userData
);
993 case B_PIC_SET_ORIGIN
:
995 const BPoint
* origin
;
996 if (callbacks
.set_origin
== NULL
|| !reader
.Get(origin
))
999 callbacks
.set_origin(userData
, *origin
);
1003 case B_PIC_SET_PEN_LOCATION
:
1005 const BPoint
* location
;
1006 if (callbacks
.set_pen_location
== NULL
|| !reader
.Get(location
))
1009 callbacks
.set_pen_location(userData
, *location
);
1013 case B_PIC_SET_DRAWING_MODE
:
1016 if (callbacks
.set_drawing_mode
== NULL
|| !reader
.Get(mode
))
1019 callbacks
.set_drawing_mode(userData
, (drawing_mode
)*mode
);
1023 case B_PIC_SET_LINE_MODE
:
1025 const uint16
* capMode
;
1026 const uint16
* joinMode
;
1027 const float* miterLimit
;
1028 if (callbacks
.set_line_mode
== NULL
|| !reader
.Get(capMode
)
1029 || !reader
.Get(joinMode
) || !reader
.Get(miterLimit
)) {
1033 callbacks
.set_line_mode(userData
, (cap_mode
)*capMode
,
1034 (join_mode
)*joinMode
, *miterLimit
);
1038 case B_PIC_SET_PEN_SIZE
:
1040 const float* penSize
;
1041 if (callbacks
.set_pen_size
== NULL
|| !reader
.Get(penSize
))
1044 callbacks
.set_pen_size(userData
, *penSize
);
1048 case B_PIC_SET_FORE_COLOR
:
1050 const rgb_color
* color
;
1051 if (callbacks
.set_fore_color
== NULL
|| !reader
.Get(color
))
1054 callbacks
.set_fore_color(userData
, *color
);
1058 case B_PIC_SET_BACK_COLOR
:
1060 const rgb_color
* color
;
1061 if (callbacks
.set_back_color
== NULL
|| !reader
.Get(color
))
1064 callbacks
.set_back_color(userData
, *color
);
1068 case B_PIC_SET_STIPLE_PATTERN
:
1070 const pattern
* stipplePattern
;
1071 if (callbacks
.set_stipple_pattern
== NULL
1072 || !reader
.Get(stipplePattern
)) {
1076 callbacks
.set_stipple_pattern(userData
, *stipplePattern
);
1080 case B_PIC_SET_SCALE
:
1083 if (callbacks
.set_scale
== NULL
|| !reader
.Get(scale
))
1086 callbacks
.set_scale(userData
, *scale
);
1090 case B_PIC_SET_FONT_FAMILY
:
1094 if (callbacks
.set_font_family
== NULL
1095 || !reader
.GetRemaining(family
, length
)) {
1099 callbacks
.set_font_family(userData
, family
, length
);
1103 case B_PIC_SET_FONT_STYLE
:
1107 if (callbacks
.set_font_style
== NULL
1108 || !reader
.GetRemaining(style
, length
)) {
1112 callbacks
.set_font_style(userData
, style
, length
);
1116 case B_PIC_SET_FONT_SPACING
:
1118 const uint32
* spacing
;
1119 if (callbacks
.set_font_spacing
== NULL
|| !reader
.Get(spacing
))
1122 callbacks
.set_font_spacing(userData
, *spacing
);
1126 case B_PIC_SET_FONT_SIZE
:
1129 if (callbacks
.set_font_size
== NULL
|| !reader
.Get(size
))
1132 callbacks
.set_font_size(userData
, *size
);
1136 case B_PIC_SET_FONT_ROTATE
:
1138 const float* rotation
;
1139 if (callbacks
.set_font_rotation
== NULL
1140 || !reader
.Get(rotation
)) {
1144 callbacks
.set_font_rotation(userData
, *rotation
);
1148 case B_PIC_SET_FONT_ENCODING
:
1150 const uint32
* encoding
;
1151 if (callbacks
.set_font_encoding
== NULL
1152 || !reader
.Get(encoding
)) {
1156 callbacks
.set_font_encoding(userData
, *encoding
);
1160 case B_PIC_SET_FONT_FLAGS
:
1162 const uint32
* flags
;
1163 if (callbacks
.set_font_flags
== NULL
|| !reader
.Get(flags
))
1166 callbacks
.set_font_flags(userData
, *flags
);
1170 case B_PIC_SET_FONT_SHEAR
:
1173 if (callbacks
.set_font_shear
== NULL
|| !reader
.Get(shear
))
1176 callbacks
.set_font_shear(userData
, *shear
);
1180 case B_PIC_SET_FONT_FACE
:
1183 if (callbacks
.set_font_face
== NULL
|| !reader
.Get(face
))
1186 callbacks
.set_font_face(userData
, *face
);
1190 case B_PIC_SET_BLENDING_MODE
:
1192 const uint16
* alphaSourceMode
;
1193 const uint16
* alphaFunctionMode
;
1194 if (callbacks
.set_blending_mode
== NULL
1195 || !reader
.Get(alphaSourceMode
)
1196 || !reader
.Get(alphaFunctionMode
)) {
1200 callbacks
.set_blending_mode(userData
,
1201 (source_alpha
)*alphaSourceMode
,
1202 (alpha_function
)*alphaFunctionMode
);
1206 case B_PIC_SET_TRANSFORM
:
1208 const BAffineTransform
* transform
;
1209 if (callbacks
.set_transform
== NULL
|| !reader
.Get(transform
))
1212 callbacks
.set_transform(userData
, *transform
);
1216 case B_PIC_AFFINE_TRANSLATE
:
1220 if (callbacks
.translate_by
== NULL
|| !reader
.Get(x
)
1221 || !reader
.Get(y
)) {
1225 callbacks
.translate_by(userData
, *x
, *y
);
1229 case B_PIC_AFFINE_SCALE
:
1233 if (callbacks
.scale_by
== NULL
|| !reader
.Get(x
)
1234 || !reader
.Get(y
)) {
1238 callbacks
.scale_by(userData
, *x
, *y
);
1242 case B_PIC_AFFINE_ROTATE
:
1244 const double* angleRadians
;
1245 if (callbacks
.rotate_by
== NULL
|| !reader
.Get(angleRadians
))
1248 callbacks
.rotate_by(userData
, *angleRadians
);
1252 case B_PIC_BLEND_LAYER
:
1254 Layer
* const* layer
;
1255 if (callbacks
.blend_layer
== NULL
|| !reader
.Get
<Layer
*>(layer
))
1258 callbacks
.blend_layer(userData
, *layer
);
1262 case B_PIC_CLIP_TO_RECT
:
1264 const bool* inverse
;
1267 if (callbacks
.clip_to_rect
== NULL
|| !reader
.Get(inverse
)
1268 || !reader
.Get(rect
)) {
1272 callbacks
.clip_to_rect(userData
, *rect
, *inverse
);
1276 case B_PIC_CLIP_TO_SHAPE
:
1278 const bool* inverse
;
1279 const uint32
* opCount
;
1280 const uint32
* pointCount
;
1281 const uint32
* opList
;
1282 const BPoint
* pointList
;
1283 if (callbacks
.clip_to_shape
== NULL
|| !reader
.Get(inverse
)
1284 || !reader
.Get(opCount
) || !reader
.Get(pointCount
)
1285 || !reader
.Get(opList
, *opCount
)
1286 || !reader
.Get(pointList
, *pointCount
)) {
1290 callbacks
.clip_to_shape(userData
, *opCount
, opList
,
1291 *pointCount
, pointList
, *inverse
);
1302 printf("executed in %" B_PRId64
" usecs\n", system_time()
1309 printf("Done! %" B_PRId32
" ops, rendering completed in %" B_PRId64
1310 " usecs.\n", numOps
, system_time() - startTime
);