Appendix A
#include <stdio.h>
typedef unsigned char byte;
class TAlphaPlane
{
public:
int GetScreenWidth() throw ()
{
return 720;
}
int GetScreenHeight() throw ()
{
return 576;
}
void FillRectangle(int top, int left, int bottom, int right,
byte value) throw ()
{
printf("Fill rectangle at (%d, %d) by (%d, %d), with value %u.\n",
top, left, bottom, right, value);
}
};
class TVideoMixer
{
public:
enum { TRANSPARENT = 0 };
enum { OPAQUE = 255 };
private:
TAlphaPlane& AlphaPlane;
bool VideoEnabled, Alpha0Enabled, Alpha1Enabled;
int VideoTop, VideoLeft, VideoBottom, VideoRight;
int Alpha0Top, Alpha0Left, Alpha0Bottom, Alpha0Right;
int Alpha1Top, Alpha1Left, Alpha1Bottom, Alpha1Right;
int Alpha0Value, Alpha0Depth;
int Alpha1Value, Alpha1Depth;
void PaintAll() throw ();
public:
TVideoMixer(TAlphaPlane& plane) throw ();
void ShowVideoWindow(int top, int left, int bottom, int right) throw ();
void HideVideoWindow() throw ();
int GetAlphaWindowCount() throw ();
void ShowAlphaWindow(int id, int top, int left, int bottom, int right,
int opacity, int depth) throw ();
void HideAlphaWindow(int id) throw ();
};
void TVideoMixer::PaintAll() throw ()
{
int dTop, dLeft, dBottom, dRight;
AlphaPlane.FillRectangle(VideoTop, VideoLeft, VideoBottom, VideoRight,
TRANSPARENT);
if (Alpha0Enabled && Alpha0Depth > Alpha1Depth) {
// Alpha window 0 is placed below alpha window 1 (i.e. paint this first).
dTop = (VideoTop > Alpha0Top ? VideoTop : Alpha0Top);
dLeft = (VideoLeft > Alpha0Left ? VideoLeft : Alpha0Left);
dBottom = (VideoBottom < Alpha0Bottom ? VideoBottom : Alpha0Bottom);
dRight = (VideoRight < Alpha0Right ? VideoRight : Alpha0Right);
if (dTop < dBottom && dLeft < dRight) {
AlphaPlane.FillRectangle(dTop, dLeft, dBottom, dRight, Alpha0Value);
}
}
if (Alpha1Enabled) {
dTop = (VideoTop > Alpha1Top ? VideoTop : Alpha1Top);
dLeft = (VideoLeft > Alpha1Left ? VideoLeft : Alpha1Left);
dBottom = (VideoBottom < Alpha1Bottom ? VideoBottom : Alpha1Bottom);
dRight = (VideoRight < Alpha1Right ? VideoRight : Alpha1Right);
if (dTop < dBottom && dLeft < dRight) {
AlphaPlane.FillRectangle(dTop, dLeft, dBottom, dRight, Alpha1Value);
}
}
if (Alpha0Enabled && Alpha0Depth < Alpha1Depth) {
// Alpha window 0 is placed above alpha window 1 (i.e. paint this last).
dTop = (VideoTop > Alpha0Top ? VideoTop : Alpha0Top);
dLeft = (VideoLeft > Alpha0Left ? VideoLeft : Alpha0Left);
dBottom = (VideoBottom < Alpha0Bottom ? VideoBottom : Alpha0Bottom);
dRight = (VideoRight < Alpha0Right ? VideoRight : Alpha0Right);
if (dTop < dBottom && dLeft < dRight) {
AlphaPlane.FillRectangle(dTop, dLeft, dBottom, dRight, Alpha0Value);
}
}
}
TVideoMixer::TVideoMixer(TAlphaPlane& plane) throw ()
: AlphaPlane(plane)
{
VideoEnabled = false;
Alpha0Enabled = false;
Alpha1Enabled = false;
Alpha0Depth = 0;
Alpha1Depth = 1;
AlphaPlane.FillRectangle(0, 0, plane.GetScreenWidth(),
plane.GetScreenHeight(), OPAQUE);
}
void TVideoMixer::ShowVideoWindow(int top, int left,
int bottom, int right)
throw ()
{
// First erase all alpha windows.
if (VideoEnabled) {
AlphaPlane.FillRectangle(VideoTop, VideoLeft, VideoBottom, VideoRight,
OPAQUE);
}
VideoTop = top;
VideoLeft = left;
VideoBottom = bottom;
VideoRight = right;
VideoEnabled = true;
PaintAll();
}
void TVideoMixer::HideVideoWindow() throw ()
{
if (VideoEnabled) {
AlphaPlane.FillRectangle(VideoTop, VideoLeft, VideoBottom, VideoRight,
OPAQUE);
}
VideoEnabled = false;
}
int TVideoMixer::GetAlphaWindowCount() throw ()
{
return 2;
}
void TVideoMixer::ShowAlphaWindow(int id,
int top, int left,
int bottom, int right,
int opacity, int depth)
throw ()
{
if (id == 0) {
Alpha0Top = top;
Alpha0Left = left;
Alpha0Bottom = bottom;
Alpha0Right = right;
Alpha0Enabled = true;
Alpha0Value = opacity;
if (depth != Alpha0Depth) {
// Swap z-order of alpha windows.
Alpha1Depth = Alpha0Depth;
Alpha0Depth = depth;
}
}
else {
Alpha1Top = top;
Alpha1Left = left;
Alpha1Bottom = bottom;
Alpha1Right = right;
Alpha1Enabled = true;
Alpha1Value = opacity;
if (depth != Alpha1Depth) {
// Swap z-order of alpha windows.
Alpha0Depth = Alpha1Depth;
Alpha1Depth = depth;
}
}
//! depth range not checked
if (VideoEnabled) {
AlphaPlane.FillRectangle(VideoTop, VideoLeft, VideoBottom, VideoRight,
OPAQUE);
PaintAll();
}
}
void TVideoMixer::HideAlphaWindow(int id) throw ()
{
if (id == 0) {
Alpha0Enabled = false;
}
else {
Alpha1Enabled = false;
}
if (VideoEnabled) {
AlphaPlane.FillRectangle(VideoTop, VideoLeft, VideoBottom, VideoRight,
OPAQUE);
PaintAll();
}
}
int main(int atgc, char* argv[])
{
TAlphaPlane alphaPlane;
TVideoMixer videoMixer(alphaPlane);
printf("=== ShowVideoWindow(10, 10, 100, 100) ===\n");
videoMixer.ShowVideoWindow(10, 10, 100, 100);
printf("=== ShowAlphaWindow(0, 30, 30, 70, 70, 127, 0) ===\n");
videoMixer.ShowAlphaWindow(0, 30, 30, 70, 70, 127, 0);
printf("=== ShowAlphaWindow(0, 90, 30, 130, 70, 127, 0) ===\n");
videoMixer.ShowAlphaWindow(0, 90, 30, 130, 70, 127, 0);
printf("=== ShowAlphaWindow(1, 30, 30, 70, 70, 77, 0) ===\n");
videoMixer.ShowAlphaWindow(1, 30, 30, 70, 70, 77, 0);
printf("=== HideVideoWindow() ===\n");
videoMixer.HideVideoWindow();
printf("=== ShowAlphaWindow(0, 40, 40, 80, 80, 127, 0) ===\n");
videoMixer.ShowAlphaWindow(0, 40, 40, 80, 80, 127, 0);
printf("=== ShowVideoWindow(10, 10, 100, 100) ===\n");
videoMixer.ShowVideoWindow(10, 10, 100, 100);
}