//------------------------------------------------------------------------------ // Copyright (c) 2001-2002, OpenBeOS // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // File Name: TPicture.cpp // Author: Marc Flerackers (mflerackers@androme.be) // Description: TPicture is used to create and play picture data. //------------------------------------------------------------------------------ // Standard Includes ----------------------------------------------------------- #include // System Includes ------------------------------------------------------------- #include #include // Project Includes ------------------------------------------------------------ // Local Includes -------------------------------------------------------------- // Local Defines --------------------------------------------------------------- // Globals --------------------------------------------------------------------- typedef void (*fnc)(void*); typedef void (*fnc_BPoint)(void*, BPoint); typedef void (*fnc_BPointBPoint)(void*, BPoint, BPoint); typedef void (*fnc_BRect)(void*, BRect); typedef void (*fnc_BRectBPoint)(void*, BRect, BPoint); typedef void (*fnc_PBPoint)(void*, BPoint*); typedef void (*fnc_i)(void*, int32); typedef void (*fnc_iPBPointb)(void*, int32, BPoint*, bool); typedef void (*fnc_iPBPoint)(void*, int32, BPoint*); typedef void (*fnc_Pc)(void*, char*); typedef void (*fnc_Pcff)(void*, char*, float, float); typedef void (*fnc_BPointBPointff)(void*, BPoint, BPoint, float, float); typedef void (*fnc_s)(void*, int16); typedef void (*fnc_ssf)(void*, int16, int16, float); typedef void (*fnc_f)(void*, float); typedef void (*fnc_Color)(void*, rgb_color); typedef void (*fnc_Pattern)(void*, pattern); typedef void (*fnc_PBRecti)(void*, BRect*, int32); typedef void (*fnc_DrawPixels)(void *, BRect, BRect, int32, int32, int32, int32, int32, void*); //------------------------------------------------------------------------------ TPicture::TPicture(void *data, int32 size, BList &pictures) : fData(data, size), fPictures(pictures) { } //------------------------------------------------------------------------------ TPicture::~TPicture() { } //------------------------------------------------------------------------------ int16 TPicture::GetOp() { int16 data; fData.Read(&data, sizeof(int16)); return data; } //------------------------------------------------------------------------------ bool TPicture::GetBool() { bool data; fData.Read(&data, sizeof(bool)); return data; } //------------------------------------------------------------------------------ int16 TPicture::GetInt16() { int16 data; fData.Read(&data, sizeof(int16)); return data; } //------------------------------------------------------------------------------ int32 TPicture::GetInt32() { int32 data; fData.Read(&data, sizeof(int32)); return data; } //------------------------------------------------------------------------------ float TPicture::GetFloat() { float data; fData.Read(&data, sizeof(float)); return data; } //------------------------------------------------------------------------------ BPoint TPicture::GetCoord() { BPoint data; fData.Read(&data, sizeof(BPoint)); return data; } //------------------------------------------------------------------------------ BRect TPicture::GetRect() { BRect data; fData.Read(&data, sizeof(BRect)); return data; } //------------------------------------------------------------------------------ rgb_color TPicture::GetColor() { rgb_color data; fData.Read(&data, sizeof(rgb_color)); return data; } //------------------------------------------------------------------------------ void TPicture::GetData(void *data, int32 size) { fData.Read(data, size); } //------------------------------------------------------------------------------ status_t TPicture::Play(void **callBackTable, int32 tableEntries, void *userData) { // TODO: we should probably check if the functions in the table are not 0 // before calling them. int16 op=0; int32 size=0; off_t pos=0; while (fData.Position() < size) { op = GetOp(); size = GetInt32(); pos = fData.Position(); switch (op) { case B_PIC_MOVE_PEN_BY: { BPoint where = GetCoord(); ((fnc_BPoint)callBackTable[1])(userData, where); break; } case B_PIC_STROKE_LINE: { BPoint start = GetCoord(); BPoint end = GetCoord(); ((fnc_BPointBPoint)callBackTable[2])(userData, start, end); break; } case B_PIC_STROKE_RECT: { BRect rect = GetRect(); ((fnc_BRect)callBackTable[3])(userData, rect); break; } case B_PIC_FILL_RECT: { BRect rect = GetRect(); ((fnc_BRect)callBackTable[4])(userData, rect); break; } case B_PIC_STROKE_ROUND_RECT: { BRect rect = GetRect(); BPoint radii = GetCoord(); ((fnc_BRectBPoint)callBackTable[5])(userData, rect, radii); break; } case B_PIC_FILL_ROUND_RECT: { BRect rect = GetRect(); BPoint radii = GetCoord(); ((fnc_BRectBPoint)callBackTable[6])(userData, rect, radii); break; } case B_PIC_STROKE_BEZIER: { BPoint control[4]; GetData(control, sizeof(control)); ((fnc_PBPoint)callBackTable[7])(userData, control); break; } case B_PIC_FILL_BEZIER: { BPoint control[4]; GetData(control, sizeof(control)); ((fnc_PBPoint)callBackTable[8])(userData, control); break; } case B_PIC_STROKE_POLYGON: { int32 numPoints = GetInt32(); BPoint *points = new BPoint[numPoints]; GetData(points, numPoints * sizeof(BPoint)); bool isClosed = GetBool(); ((fnc_iPBPointb)callBackTable[13])(userData, numPoints, points, isClosed); delete points; break; } case B_PIC_FILL_POLYGON: { int32 numPoints = GetInt32(); BPoint *points = new BPoint[numPoints]; GetData(points, numPoints * sizeof(BPoint)); ((fnc_iPBPoint)callBackTable[14])(userData, numPoints, points); delete points; break; } case B_PIC_STROKE_SHAPE: case B_PIC_FILL_SHAPE: break; case B_PIC_DRAW_STRING: { int32 len = GetInt32(); char *string = new char[len + 1]; GetData(string, len); string[len] = '\0'; float deltax = GetFloat(); float deltay = GetFloat(); ((fnc_Pcff)callBackTable[17])(userData, string, deltax, deltay); delete string; break; } case B_PIC_DRAW_PIXELS: { BRect src = GetRect(); BRect dest = GetRect(); int32 width = GetInt32(); int32 height = GetInt32(); int32 bytesPerRow = GetInt32(); int32 pixelFormat = GetInt32(); int32 flags = GetInt32(); char *data = new char[size - (fData.Position() - pos)]; GetData(data, size - (fData.Position() - pos)); ((fnc_DrawPixels)callBackTable[18])(userData, src, dest, width, height, bytesPerRow, pixelFormat, flags, data); delete data; break; } case B_PIC_DRAW_PICTURE: { break; } case B_PIC_STROKE_ARC: { BPoint center = GetCoord(); BPoint radii = GetCoord(); float startTheta = GetFloat(); float arcTheta = GetFloat(); ((fnc_BPointBPointff)callBackTable[9])(userData, center, radii, startTheta, arcTheta); break; } case B_PIC_FILL_ARC: { BPoint center = GetCoord(); BPoint radii = GetCoord(); float startTheta = GetFloat(); float arcTheta = GetFloat(); ((fnc_BPointBPointff)callBackTable[10])(userData, center, radii, startTheta, arcTheta); break; } case B_PIC_STROKE_ELLIPSE: { BRect rect = GetRect(); BPoint center; BPoint radii((rect.Width() + 1) / 2.0f, (rect.Height() + 1) / 2.0f); center = rect.LeftTop() + radii; ((fnc_BPointBPoint)callBackTable[11])(userData, center, radii); break; } case B_PIC_FILL_ELLIPSE: { BRect rect = GetRect(); BPoint center; BPoint radii((rect.Width() + 1) / 2.0f, (rect.Height() + 1) / 2.0f); center = rect.LeftTop() + radii; ((fnc_BPointBPoint)callBackTable[12])(userData, center, radii); break; } case B_PIC_ENTER_STATE_CHANGE: { break; } case B_PIC_SET_CLIPPING_RECTS: { break; } case B_PIC_CLIP_TO_PICTURE: { break; } case B_PIC_PUSH_STATE: { ((fnc)callBackTable[22])(userData); break; } case B_PIC_POP_STATE: { ((fnc)callBackTable[23])(userData); break; } case B_PIC_CLEAR_CLIPPING_RECTS: { ((fnc_PBRecti)callBackTable[20])(userData, NULL, 0); break; } case B_PIC_SET_ORIGIN: { BPoint pt = GetCoord(); ((fnc_BPoint)callBackTable[28])(userData, pt); break; } case B_PIC_SET_PEN_LOCATION: { BPoint pt = GetCoord(); ((fnc_BPoint)callBackTable[29])(userData, pt); break; } case B_PIC_SET_DRAWING_MODE: { int16 mode = GetInt16(); ((fnc_s)callBackTable[30])(userData, mode); break; } case B_PIC_SET_LINE_MODE: { int16 capMode = GetInt16(); int16 joinMode = GetInt16(); float miterLimit = GetFloat(); ((fnc_ssf)callBackTable[31])(userData, capMode, joinMode, miterLimit); break; } case B_PIC_SET_PEN_SIZE: { float size = GetFloat(); ((fnc_f)callBackTable[32])(userData, size); break; } case B_PIC_SET_SCALE: { float scale = GetFloat(); ((fnc_f)callBackTable[36])(userData, scale); break; } case B_PIC_SET_FORE_COLOR: { rgb_color color = GetColor(); ((fnc_Color)callBackTable[33])(userData, color); break; } case B_PIC_SET_BACK_COLOR: { rgb_color color = GetColor(); ((fnc_Color)callBackTable[34])(userData, color); break; } case B_PIC_SET_STIPLE_PATTERN: { pattern p; GetData(&p, sizeof(p)); ((fnc_Pattern)callBackTable[35])(userData, p); break; } case B_PIC_ENTER_FONT_STATE: { ((fnc)callBackTable[26])(userData); break; } case B_PIC_SET_BLENDING_MODE: { //int16 alphaSrcMode = GetInt16(); //int16 alphaFncMode = GetInt16(); //((fnc_Pattern)callBackTable[??])(userData, alphaSrcMode, // alphaFncMode); break; } case B_PIC_SET_FONT_FAMILY: { int32 len = GetInt32(); char *string = new char[len + 1]; GetData(string, len); string[len] = '\0'; ((fnc_Pc)callBackTable[37])(userData, string); delete string; break; } case B_PIC_SET_FONT_STYLE: { int32 len = GetInt32(); char *string = new char[len + 1]; GetData(string, len); string[len] = '\0'; ((fnc_Pc)callBackTable[38])(userData, string); delete string; break; } case B_PIC_SET_FONT_SPACING: { int32 spacing = GetInt32(); ((fnc_i)callBackTable[39])(userData, spacing); break; } case B_PIC_SET_FONT_ENCODING: { int32 encoding = GetInt32(); ((fnc_i)callBackTable[42])(userData, encoding); break; } case B_PIC_SET_FONT_FLAGS: { int32 flags = GetInt32(); ((fnc_i)callBackTable[43])(userData, flags); break; } case B_PIC_SET_FONT_SIZE: { float size = GetFloat(); ((fnc_f)callBackTable[40])(userData, size); break; } case B_PIC_SET_FONT_ROTATE: { float rotation = GetFloat(); ((fnc_f)callBackTable[41])(userData, rotation); break; } case B_PIC_SET_FONT_SHEAR: { float shear = GetFloat(); ((fnc_f)callBackTable[44])(userData, shear); break; } case B_PIC_SET_FONT_FACE: { int32 flags = GetInt32(); ((fnc_i)callBackTable[46])(userData, flags); break; } default: break; } // If we didn't read enough bytes, skip them. This is not a error // since the instructions can change over time. if (fData.Position() - pos < size) fData.Seek(size - (fData.Position() - pos), SEEK_CUR); // TODO: what if too much was read, should we return B_ERROR? } return B_OK; } //------------------------------------------------------------------------------