1 /* 2 * Copyright 2006-2018 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stefano Ceccherini, stefano.ceccherini@gmail.com 7 * Julian Harnath, <julian.harnath@rwth-achen.de> 8 * Stephan Aßmus <superstippi@gmx.de> 9 */ 10 11 #include <PictureDataWriter.h> 12 13 #include <stdio.h> 14 #include <string.h> 15 16 #include <DataIO.h> 17 #include <Gradient.h> 18 #include <Point.h> 19 #include <Rect.h> 20 #include <Region.h> 21 22 #include <PictureProtocol.h> 23 24 #define THROW_ERROR(error) throw (status_t)(error) 25 26 27 // TODO: Review writing of strings. AFAIK in the picture data format 28 // They are not supposed to be NULL terminated 29 // (at least, it's not mandatory) so we should write their size too. 30 PictureDataWriter::PictureDataWriter() 31 : 32 fData(NULL) 33 { 34 } 35 36 37 PictureDataWriter::PictureDataWriter(BPositionIO* data) 38 : 39 fData(data) 40 { 41 } 42 43 44 PictureDataWriter::~PictureDataWriter() 45 { 46 } 47 48 49 status_t 50 PictureDataWriter::SetTo(BPositionIO* data) 51 { 52 if (data == NULL) 53 return B_BAD_VALUE; 54 55 fData = data; 56 57 return B_OK; 58 } 59 60 61 status_t 62 PictureDataWriter::WriteSetOrigin(const BPoint& point) 63 { 64 try { 65 BeginOp(B_PIC_SET_ORIGIN); 66 Write<BPoint>(point); 67 EndOp(); 68 } catch (status_t& status) { 69 return status; 70 } 71 72 return B_OK; 73 } 74 75 76 status_t 77 PictureDataWriter::WriteInvertRect(const BRect& rect) 78 { 79 try { 80 WritePushState(); 81 WriteSetDrawingMode(B_OP_INVERT); 82 83 BeginOp(B_PIC_FILL_RECT); 84 Write<BRect>(rect); 85 EndOp(); 86 87 WritePopState(); 88 } catch (status_t& status) { 89 return status; 90 } 91 92 return B_OK; 93 } 94 95 96 status_t 97 PictureDataWriter::WriteSetDrawingMode(const drawing_mode& mode) 98 { 99 try { 100 BeginOp(B_PIC_SET_DRAWING_MODE); 101 Write<int16>((int16)mode); 102 EndOp(); 103 } catch (status_t& status) { 104 return status; 105 } 106 107 return B_OK; 108 } 109 110 111 status_t 112 PictureDataWriter::WriteSetPenLocation(const BPoint& point) 113 { 114 try { 115 BeginOp(B_PIC_SET_PEN_LOCATION); 116 Write<BPoint>(point); 117 EndOp(); 118 } catch (status_t& status) { 119 return status; 120 } 121 122 return B_OK; 123 } 124 125 126 status_t 127 PictureDataWriter::WriteSetPenSize(const float& penSize) 128 { 129 try { 130 BeginOp(B_PIC_SET_PEN_SIZE); 131 Write<float>(penSize); 132 EndOp(); 133 } catch (status_t& status) { 134 return status; 135 } 136 137 return B_OK; 138 } 139 140 141 status_t 142 PictureDataWriter::WriteSetLineMode(const cap_mode& cap, const join_mode& join, 143 const float& miterLimit) 144 { 145 try { 146 BeginOp(B_PIC_SET_LINE_MODE); 147 Write<int16>((int16)cap); 148 Write<int16>((int16)join); 149 Write<float>(miterLimit); 150 EndOp(); 151 } catch (status_t& status) { 152 return status; 153 } 154 155 return B_OK; 156 } 157 158 159 status_t 160 PictureDataWriter::WriteSetFillRule(int32 fillRule) 161 { 162 try { 163 BeginOp(B_PIC_SET_FILL_RULE); 164 Write<int32>(fillRule); 165 EndOp(); 166 } catch (status_t& status) { 167 return status; 168 } 169 170 return B_OK; 171 } 172 173 174 status_t 175 PictureDataWriter::WriteSetScale(const float& scale) 176 { 177 try { 178 BeginOp(B_PIC_SET_SCALE); 179 Write<float>(scale); 180 EndOp(); 181 } catch (status_t& status) { 182 return status; 183 } 184 185 return B_OK; 186 } 187 188 189 status_t 190 PictureDataWriter::WriteSetTransform(BAffineTransform transform) 191 { 192 try { 193 BeginOp(B_PIC_SET_TRANSFORM); 194 Write<BAffineTransform>(transform); 195 EndOp(); 196 } catch (status_t& status) { 197 return status; 198 } 199 200 return B_OK; 201 } 202 203 204 status_t 205 PictureDataWriter::WriteTranslateBy(double x, double y) 206 { 207 try { 208 BeginOp(B_PIC_AFFINE_TRANSLATE); 209 Write<double>(x); 210 Write<double>(y); 211 EndOp(); 212 } catch (status_t& status) { 213 return status; 214 } 215 216 return B_OK; 217 } 218 219 220 status_t 221 PictureDataWriter::WriteScaleBy(double x, double y) 222 { 223 try { 224 BeginOp(B_PIC_AFFINE_SCALE); 225 Write<double>(x); 226 Write<double>(y); 227 EndOp(); 228 } catch (status_t& status) { 229 return status; 230 } 231 232 return B_OK; 233 } 234 235 236 status_t 237 PictureDataWriter::WriteRotateBy(double angleRadians) 238 { 239 try { 240 BeginOp(B_PIC_AFFINE_ROTATE); 241 Write<double>(angleRadians); 242 EndOp(); 243 } catch (status_t& status) { 244 return status; 245 } 246 247 return B_OK; 248 } 249 250 251 status_t 252 PictureDataWriter::WriteSetPattern(const ::pattern& pattern) 253 { 254 try { 255 BeginOp(B_PIC_SET_STIPLE_PATTERN); 256 Write< ::pattern>(pattern); 257 EndOp(); 258 } catch (status_t& status) { 259 return status; 260 } 261 262 return B_OK; 263 } 264 265 266 status_t 267 PictureDataWriter::WriteClipToPicture(int32 pictureToken, 268 const BPoint& origin, bool inverse) 269 { 270 // TODO: I don't know if it's compatible with R5's BPicture version 271 try { 272 BeginOp(B_PIC_CLIP_TO_PICTURE); 273 Write<int32>(pictureToken); 274 Write<BPoint>(origin); 275 Write<bool>(inverse); 276 EndOp(); 277 } catch (status_t& status) { 278 return status; 279 } 280 281 return B_OK; 282 } 283 284 285 status_t 286 PictureDataWriter::WriteSetClipping(const BRegion& region) 287 { 288 // TODO: I don't know if it's compatible with R5's BPicture version 289 try { 290 const int32 numRects = region.CountRects(); 291 if (numRects > 0 && region.Frame().IsValid()) { 292 BeginOp(B_PIC_SET_CLIPPING_RECTS); 293 Write<uint32>(numRects); 294 for (int32 i = 0; i < numRects; i++) 295 Write<BRect>(region.RectAt(i)); 296 297 EndOp(); 298 } else 299 WriteClearClipping(); 300 } catch (status_t& status) { 301 return status; 302 } 303 304 return B_OK; 305 } 306 307 308 status_t 309 PictureDataWriter::WriteClearClipping() 310 { 311 try { 312 BeginOp(B_PIC_CLEAR_CLIPPING_RECTS); 313 EndOp(); 314 } catch (status_t& status) { 315 return status; 316 } 317 318 return B_OK; 319 } 320 321 322 status_t 323 PictureDataWriter::WriteSetHighColor(const rgb_color& color) 324 { 325 try { 326 BeginOp(B_PIC_SET_FORE_COLOR); 327 Write<rgb_color>(color); 328 EndOp(); 329 } catch (status_t& status) { 330 return status; 331 } 332 333 return B_OK; 334 } 335 336 337 status_t 338 PictureDataWriter::WriteSetLowColor(const rgb_color& color) 339 { 340 try { 341 BeginOp(B_PIC_SET_BACK_COLOR); 342 Write<rgb_color>(color); 343 EndOp(); 344 } catch (status_t& status) { 345 return status; 346 } 347 348 return B_OK; 349 } 350 351 352 status_t 353 PictureDataWriter::WriteDrawRect(const BRect& rect, const bool& fill) 354 { 355 try { 356 BeginOp(fill ? B_PIC_FILL_RECT : B_PIC_STROKE_RECT); 357 Write<BRect>(rect); 358 EndOp(); 359 } catch (status_t& status) { 360 return status; 361 } 362 363 return B_OK; 364 } 365 366 367 status_t 368 PictureDataWriter::WriteDrawRoundRect(const BRect& rect, const BPoint& radius, 369 const bool& fill) 370 { 371 try { 372 BeginOp(fill ? B_PIC_FILL_ROUND_RECT : B_PIC_STROKE_ROUND_RECT); 373 Write<BRect>(rect); 374 Write<BPoint>(radius); 375 EndOp(); 376 } catch (status_t& status) { 377 return status; 378 } 379 380 return B_OK; 381 } 382 383 384 status_t 385 PictureDataWriter::WriteDrawEllipse(const BRect& rect, const bool& fill) 386 { 387 try { 388 BeginOp(fill ? B_PIC_FILL_ELLIPSE : B_PIC_STROKE_ELLIPSE); 389 Write<BRect>(rect); 390 EndOp(); 391 } catch (status_t& status) { 392 return status; 393 } 394 395 return B_OK; 396 } 397 398 399 status_t 400 PictureDataWriter::WriteDrawArc(const BPoint& center, const BPoint& radius, 401 const float& startTheta, const float& arcTheta, const bool& fill) 402 { 403 try { 404 BeginOp(fill ? B_PIC_FILL_ARC : B_PIC_STROKE_ARC); 405 Write<BPoint>(center); 406 Write<BPoint>(radius); 407 Write<float>(startTheta); 408 Write<float>(arcTheta); 409 EndOp(); 410 } catch (status_t& status) { 411 return status; 412 } 413 414 return B_OK; 415 } 416 417 418 status_t 419 PictureDataWriter::WriteDrawPolygon(const int32& numPoints, BPoint* points, 420 const bool& isClosed, const bool& fill) 421 { 422 try { 423 BeginOp(fill ? B_PIC_FILL_POLYGON : B_PIC_STROKE_POLYGON); 424 Write<int32>(numPoints); 425 for (int32 i = 0; i < numPoints; i++) 426 Write<BPoint>(points[i]); 427 428 if (!fill) 429 Write<uint8>((uint8)isClosed); 430 431 EndOp(); 432 } catch (status_t& status) { 433 return status; 434 } 435 436 return B_OK; 437 } 438 439 440 status_t 441 PictureDataWriter::WriteDrawBezier(const BPoint points[4], const bool& fill) 442 { 443 try { 444 BeginOp(fill ? B_PIC_FILL_BEZIER : B_PIC_STROKE_BEZIER); 445 for (int32 i = 0; i < 4; i++) 446 Write<BPoint>(points[i]); 447 448 EndOp(); 449 } catch (status_t& status) { 450 return status; 451 } 452 453 return B_OK; 454 } 455 456 457 status_t 458 PictureDataWriter::WriteStrokeLine(const BPoint& start, const BPoint& end) 459 { 460 try { 461 BeginOp(B_PIC_STROKE_LINE); 462 Write<BPoint>(start); 463 Write<BPoint>(end); 464 EndOp(); 465 } catch (status_t& status) { 466 return status; 467 } 468 469 return B_OK; 470 } 471 472 473 status_t 474 PictureDataWriter::WriteDrawString(const BPoint& where, const char* string, 475 const int32& length, const escapement_delta& escapement) 476 { 477 try { 478 BeginOp(B_PIC_SET_PEN_LOCATION); 479 Write<BPoint>(where); 480 EndOp(); 481 482 BeginOp(B_PIC_DRAW_STRING); 483 Write<float>(escapement.space); 484 Write<float>(escapement.nonspace); 485 //WriteData(string, length + 1); 486 // TODO: is string 0 terminated? why is length given? 487 WriteData(string, length); 488 Write<uint8>(0); 489 EndOp(); 490 } catch (status_t& status) { 491 return status; 492 } 493 494 return B_OK; 495 } 496 497 498 status_t 499 PictureDataWriter::WriteDrawString(const char* string, 500 int32 length, const BPoint* locations, int32 locationCount) 501 { 502 try { 503 BeginOp(B_PIC_DRAW_STRING_LOCATIONS); 504 Write<int32>(locationCount); 505 for (int32 i = 0; i < locationCount; i++) { 506 Write<BPoint>(locations[i]); 507 } 508 WriteData(string, length); 509 Write<uint8>(0); 510 EndOp(); 511 } catch (status_t& status) { 512 return status; 513 } 514 515 return B_OK; 516 } 517 518 519 status_t 520 PictureDataWriter::WriteDrawShape(const int32& opCount, const void* opList, 521 const int32& ptCount, const void* ptList, const bool& fill) 522 { 523 try { 524 BeginOp(fill ? B_PIC_FILL_SHAPE : B_PIC_STROKE_SHAPE); 525 Write<int32>(opCount); 526 Write<int32>(ptCount); 527 WriteData(opList, opCount * sizeof(uint32)); 528 WriteData(ptList, ptCount * sizeof(BPoint)); 529 EndOp(); 530 } catch (status_t& status) { 531 return status; 532 } 533 534 return B_OK; 535 } 536 537 538 status_t 539 PictureDataWriter::WriteDrawRectGradient(const BRect& rect, const BGradient& gradient, const bool& fill) 540 { 541 try { 542 BeginOp(fill ? B_PIC_FILL_RECT_GRADIENT : B_PIC_STROKE_RECT_GRADIENT); 543 Write<BRect>(rect); 544 gradient.Flatten(fData); 545 EndOp(); 546 } catch (status_t& status) { 547 return status; 548 } 549 550 return B_OK; 551 } 552 553 554 status_t 555 PictureDataWriter::WriteDrawRoundRectGradient(const BRect& rect, const BPoint& radius, const BGradient& gradient, 556 const bool& fill) 557 { 558 try { 559 BeginOp(fill ? B_PIC_FILL_ROUND_RECT_GRADIENT : B_PIC_STROKE_ROUND_RECT_GRADIENT); 560 Write<BRect>(rect); 561 Write<BPoint>(radius); 562 gradient.Flatten(fData); 563 EndOp(); 564 } catch (status_t& status) { 565 return status; 566 } 567 568 return B_OK; 569 } 570 571 572 status_t 573 PictureDataWriter::WriteDrawBezierGradient(const BPoint points[4], const BGradient& gradient, const bool& fill) 574 { 575 try { 576 BeginOp(fill ? B_PIC_FILL_BEZIER_GRADIENT : B_PIC_STROKE_BEZIER_GRADIENT); 577 for (int32 i = 0; i < 4; i++) 578 Write<BPoint>(points[i]); 579 580 gradient.Flatten(fData); 581 EndOp(); 582 } catch (status_t& status) { 583 return status; 584 } 585 586 return B_OK; 587 } 588 589 590 status_t 591 PictureDataWriter::WriteDrawArcGradient(const BPoint& center, const BPoint& radius, 592 const float& startTheta, const float& arcTheta, const BGradient& gradient, const bool& fill) 593 { 594 try { 595 BeginOp(fill ? B_PIC_FILL_ARC_GRADIENT : B_PIC_STROKE_ARC_GRADIENT); 596 Write<BPoint>(center); 597 Write<BPoint>(radius); 598 Write<float>(startTheta); 599 Write<float>(arcTheta); 600 gradient.Flatten(fData); 601 EndOp(); 602 } catch (status_t& status) { 603 return status; 604 } 605 606 return B_OK; 607 } 608 609 610 status_t 611 PictureDataWriter::WriteDrawEllipseGradient(const BRect& rect, const BGradient& gradient, const bool& fill) 612 { 613 try { 614 BeginOp(fill ? B_PIC_FILL_ELLIPSE_GRADIENT : B_PIC_STROKE_ELLIPSE_GRADIENT); 615 Write<BRect>(rect); 616 gradient.Flatten(fData); 617 EndOp(); 618 } catch (status_t& status) { 619 return status; 620 } 621 622 return B_OK; 623 } 624 625 626 status_t 627 PictureDataWriter::WriteDrawPolygonGradient(const int32& numPoints, BPoint* points, 628 const bool& isClosed, const BGradient& gradient, const bool& fill) 629 { 630 try { 631 BeginOp(fill ? B_PIC_FILL_POLYGON_GRADIENT : B_PIC_STROKE_POLYGON_GRADIENT); 632 Write<int32>(numPoints); 633 for (int32 i = 0; i < numPoints; i++) 634 Write<BPoint>(points[i]); 635 636 if (!fill) 637 Write<uint8>((uint8)isClosed); 638 639 gradient.Flatten(fData); 640 EndOp(); 641 } catch (status_t& status) { 642 return status; 643 } 644 645 return B_OK; 646 } 647 648 649 status_t 650 PictureDataWriter::WriteDrawShapeGradient(const int32& opCount, const void* opList, 651 const int32& ptCount, const void* ptList, const BGradient& gradient, const bool& fill) 652 { 653 try { 654 BeginOp(fill ? B_PIC_FILL_SHAPE_GRADIENT : B_PIC_STROKE_SHAPE_GRADIENT); 655 Write<int32>(opCount); 656 Write<int32>(ptCount); 657 WriteData(opList, opCount * sizeof(uint32)); 658 WriteData(ptList, ptCount * sizeof(BPoint)); 659 gradient.Flatten(fData); 660 EndOp(); 661 } catch (status_t& status) { 662 return status; 663 } 664 665 return B_OK; 666 } 667 668 669 status_t 670 PictureDataWriter::WriteDrawBitmap(const BRect& srcRect, const BRect& dstRect, 671 const int32& width, const int32& height, const int32& bytesPerRow, 672 const int32& colorSpace, const int32& flags, const void* data, 673 const int32& length) 674 { 675 if (length != height * bytesPerRow) 676 debugger("PictureDataWriter::WriteDrawBitmap: invalid length"); 677 try { 678 BeginOp(B_PIC_DRAW_PIXELS); 679 Write<BRect>(srcRect); 680 Write<BRect>(dstRect); 681 Write<int32>(width); 682 Write<int32>(height); 683 Write<int32>(bytesPerRow); 684 Write<int32>(colorSpace); 685 Write<int32>(flags); 686 WriteData(data, length); 687 EndOp(); 688 } catch (status_t& status) { 689 return status; 690 } 691 692 return B_OK; 693 } 694 695 696 status_t 697 PictureDataWriter::WriteDrawPicture(const BPoint& where, const int32& token) 698 { 699 // TODO: I'm not sure about this function. I think we need 700 // to attach the picture data too. 701 // The token won't be sufficient in many cases (for example, when 702 // we archive/flatten the picture. 703 try { 704 BeginOp(B_PIC_DRAW_PICTURE); 705 Write<BPoint>(where); 706 Write<int32>(token); 707 EndOp(); 708 } catch (status_t& status) { 709 return status; 710 } 711 712 return B_OK; 713 } 714 715 716 status_t 717 PictureDataWriter::WriteSetFontFamily(const font_family family) 718 { 719 try { 720 BeginOp(B_PIC_SET_FONT_FAMILY); 721 WriteData(family, strlen(family)); 722 Write<uint8>(0); 723 EndOp(); 724 } catch (status_t& status) { 725 return status; 726 } 727 728 return B_OK; 729 } 730 731 732 status_t 733 PictureDataWriter::WriteSetFontStyle(const font_style style) 734 { 735 try { 736 BeginOp(B_PIC_SET_FONT_STYLE); 737 WriteData(style, strlen(style)); 738 Write<uint8>(0); 739 EndOp(); 740 } catch (status_t& status) { 741 return status; 742 } 743 744 return B_OK; 745 } 746 747 748 status_t 749 PictureDataWriter::WriteSetFontSpacing(const int32& spacing) 750 { 751 try { 752 BeginOp(B_PIC_SET_FONT_SPACING); 753 Write<int32>(spacing); 754 EndOp(); 755 } catch (status_t& status) { 756 return status; 757 } 758 759 return B_OK; 760 } 761 762 763 status_t 764 PictureDataWriter::WriteSetFontSize(const float& size) 765 { 766 try { 767 BeginOp(B_PIC_SET_FONT_SIZE); 768 Write<float>(size); 769 EndOp(); 770 } catch (status_t& status) { 771 return status; 772 } 773 774 return B_OK; 775 } 776 777 778 status_t 779 PictureDataWriter::WriteSetFontRotation(const float& rotation) 780 { 781 try { 782 BeginOp(B_PIC_SET_FONT_ROTATE); 783 Write<float>(rotation); 784 EndOp(); 785 } catch (status_t& status) { 786 return status; 787 } 788 789 return B_OK; 790 } 791 792 793 status_t 794 PictureDataWriter::WriteSetFontEncoding(const int32& encoding) 795 { 796 try { 797 BeginOp(B_PIC_SET_FONT_ENCODING); 798 Write<int32>(encoding); 799 EndOp(); 800 } catch (status_t& status) { 801 return status; 802 } 803 804 return B_OK; 805 } 806 807 808 status_t 809 PictureDataWriter::WriteSetFontFlags(const int32& flags) 810 { 811 try { 812 BeginOp(B_PIC_SET_FONT_FLAGS); 813 Write<int32>(flags); 814 EndOp(); 815 } catch (status_t& status) { 816 return status; 817 } 818 819 return B_OK; 820 } 821 822 823 status_t 824 PictureDataWriter::WriteSetFontShear(const float& shear) 825 { 826 try { 827 BeginOp(B_PIC_SET_FONT_SHEAR); 828 Write<float>(shear); 829 EndOp(); 830 } catch (status_t& status) { 831 return status; 832 } 833 834 return B_OK; 835 } 836 837 838 status_t 839 PictureDataWriter::WriteSetFontFace(const int32& face) 840 { 841 try { 842 BeginOp(B_PIC_SET_FONT_FACE); 843 Write<int32>(face); 844 EndOp(); 845 } catch (status_t& status) { 846 return status; 847 } 848 849 return B_OK; 850 } 851 852 853 status_t 854 PictureDataWriter::WritePushState() 855 { 856 try { 857 BeginOp(B_PIC_PUSH_STATE); 858 EndOp(); 859 } catch (status_t& status) { 860 return status; 861 } 862 863 return B_OK; 864 } 865 866 867 status_t 868 PictureDataWriter::WritePopState() 869 { 870 try { 871 BeginOp(B_PIC_POP_STATE); 872 EndOp(); 873 } catch (status_t& status) { 874 return status; 875 } 876 877 return B_OK; 878 } 879 880 881 status_t 882 PictureDataWriter::WriteBlendLayer(Layer* layer) 883 { 884 try { 885 BeginOp(B_PIC_BLEND_LAYER); 886 Write<Layer*>(layer); 887 EndOp(); 888 } catch (status_t& status) { 889 return status; 890 } 891 892 return B_OK; 893 } 894 895 896 status_t 897 PictureDataWriter::WriteClipToRect(const BRect& rect, bool inverse) 898 { 899 try { 900 BeginOp(B_PIC_CLIP_TO_RECT); 901 Write<bool>(inverse); 902 Write<BRect>(rect); 903 EndOp(); 904 } catch (status_t& status) { 905 return status; 906 } 907 908 return B_OK; 909 } 910 911 912 status_t 913 PictureDataWriter::WriteClipToShape(int32 opCount, const void* opList, 914 int32 ptCount, const void* ptList, bool inverse) 915 { 916 try { 917 BeginOp(B_PIC_CLIP_TO_SHAPE); 918 Write<bool>(inverse); 919 Write<int32>(opCount); 920 Write<int32>(ptCount); 921 WriteData(opList, opCount * sizeof(uint32)); 922 WriteData(ptList, ptCount * sizeof(BPoint)); 923 EndOp(); 924 } catch (status_t& status) { 925 return status; 926 } 927 928 return B_OK; 929 } 930 931 932 // private 933 void 934 PictureDataWriter::BeginOp(const int16& op) 935 { 936 if (fData == NULL) 937 THROW_ERROR(B_NO_INIT); 938 939 fStack.push(fData->Position()); 940 fData->Write(&op, sizeof(op)); 941 942 // Init the size of the opcode block to 0 943 int32 size = 0; 944 fData->Write(&size, sizeof(size)); 945 } 946 947 948 void 949 PictureDataWriter::EndOp() 950 { 951 if (fData == NULL) 952 THROW_ERROR(B_NO_INIT); 953 954 off_t curPos = fData->Position(); 955 off_t stackPos = fStack.top(); 956 fStack.pop(); 957 958 // The size of the op is calculated like this: 959 // current position on the stream minus the position on the stack, 960 // minus the space occupied by the op code itself (int16) 961 // and the space occupied by the size field (int32) 962 int32 size = curPos - stackPos - sizeof(int32) - sizeof(int16); 963 964 // Size was set to 0 in BeginOp() 965 // Now we overwrite it with the correct value 966 fData->Seek(stackPos + sizeof(int16), SEEK_SET); 967 fData->Write(&size, sizeof(size)); 968 fData->Seek(curPos, SEEK_SET); 969 } 970 971 972 void 973 PictureDataWriter::WriteData(const void* data, size_t size) 974 { 975 ssize_t result = fData->Write(data, size); 976 if (result < 0) 977 THROW_ERROR(result); 978 979 if ((size_t)result != size) 980 THROW_ERROR(B_IO_ERROR); 981 } 982