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 ¢er, 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