00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023
00024
00025
00026 #include "DoubleBufferCanvas.h"
00027 #include "Device.h"
00028
00029
00030 DoubleBufferCanvas::DoubleBufferCanvas() : Canvas()
00031 {
00032
00033 WinHandle oldDrawWinH = WinGetDrawWindow();
00034
00035
00036 UInt16 error;
00037 screenBufferH = WinCreateOffscreenWindow(getWidth(), getHeight(), screenFormat, &error);
00038 if (error)
00039 Device::panic(error, "Cannot create double buffer.");
00040
00041
00042 WinSetDrawWindow(screenBufferH);
00043 WinEraseRectangle(&displayBounds, 0);
00044
00045
00046 WinSetDrawWindow(oldDrawWinH);
00047
00048
00049 currentBounds.topLeft.x = 0;
00050 currentBounds.topLeft.y = 0;
00051 currentBounds.extent.x = getWidth();
00052 currentBounds.extent.y = getHeight();
00053 }
00054
00055
00056 DoubleBufferCanvas::~DoubleBufferCanvas()
00057 {
00058
00059 WinDeleteWindow(screenBufferH, false);
00060 }
00061
00062
00063 void DoubleBufferCanvas::beginDraw(WinLockInitType initMode)
00064 {
00065 deviceDrawWindowH = WinGetDrawWindow();
00066 WinSetDrawWindow(screenBufferH);
00067
00068
00069 lastBounds.topLeft.x = currentBounds.topLeft.x;
00070 lastBounds.topLeft.y = currentBounds.topLeft.y;
00071 lastBounds.extent.x = currentBounds.extent.x;
00072 lastBounds.extent.y = currentBounds.extent.y;
00073
00074
00075 switch(initMode)
00076 {
00077 case winLockCopy:
00078 case winLockDontCare:
00079 break;
00080
00081 case winLockErase:
00082
00083 WinEraseRectangle(&displayBounds, 0);
00084
00085 break;
00086 default:
00087 ErrNonFatalDisplay("DoubleBufferCanvas.beginDraw: Invalid initMode");
00088 break;
00089 }
00090 }
00091
00092
00093 void DoubleBufferCanvas::endDraw(RectangleType *bounds)
00094 {
00095 ErrNonFatalDisplayIf(bounds == NULL, "DoubleBufferCanvas.endDraw: bounds == NULL");
00096
00097 WinSetDrawWindow(deviceDrawWindowH);
00098
00099 currentBounds.topLeft.x = bounds->topLeft.x;
00100 currentBounds.topLeft.y = bounds->topLeft.y;
00101 currentBounds.extent.x = bounds->extent.x;
00102 currentBounds.extent.y = bounds->extent.y;
00103
00104 Canvas::uniteBounds(&lastBounds, ¤tBounds, ©Bounds);
00105
00106
00107 copyBounds.topLeft.x = max(copyBounds.topLeft.x, 0);
00108 copyBounds.topLeft.y = max(copyBounds.topLeft.y, 0);
00109
00110 copyBounds.extent.x = min(copyBounds.extent.x, getWidth() - copyBounds.topLeft.x);
00111 copyBounds.extent.y = min(copyBounds.extent.y, getHeight() - copyBounds.topLeft.y);
00112
00113
00114 UInt16 offset = copyBounds.topLeft.x & 0x000F;
00115 if (offset)
00116 {
00117 copyBounds.topLeft.x -= offset;
00118 copyBounds.extent.x += offset;
00119 }
00120
00121
00122 copyBounds.extent.x = (copyBounds.extent.x + 0x0F) & 0xFFF0;
00123 }
00124
00125
00126 void DoubleBufferCanvas::show()
00127 {
00128
00129 WinCopyRectangle (screenBufferH, 0, ©Bounds,
00130 copyBounds.topLeft.x,
00131 copyBounds.topLeft.y,
00132 winPaint);
00133 }