00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "chanlayout.h"
00020 #include "chanparse.h"
00021 #include "chanshare.h"
00022 #include <notify.h>
00023
00024 LayoutType* LayoutDB = (LayoutType*)0;
00025
00026 class LayoutParseFunctor : public ChanParseFunctor {
00027 public:
00028 INLINE LayoutParseFunctor(void) : ChanParseFunctor() {}
00029 virtual ~LayoutParseFunctor(void);
00030
00031 virtual void operator()(std::string);
00032 };
00033
00034 LayoutParseFunctor::~LayoutParseFunctor(void) {
00035 return;
00036 }
00037
00038 typedef pvector<bool> LayoutBoolVec;
00039
00040 void LayoutParseFunctor::operator()(std::string S) {
00041 std::string sym;
00042
00043 ChanEatFrontWhite(S);
00044 sym = ChanReadNextWord(S);
00045 ChanCheckScoping(S);
00046 ChanDescope(S);
00047
00048 int X, Y;
00049
00050 X = ChanReadNextInt(S);
00051 Y = ChanReadNextInt(S);
00052
00053 LayoutItem L(X, Y);
00054 LayoutBoolVec mask;
00055 int i=0;
00056 for (; i<(X*Y); ++i)
00057 mask.push_back(false);
00058
00059 float xfrac = 1. / float(X);
00060 float yfrac = 1. / float(Y);
00061
00062 while (!S.empty()) {
00063 ChanCheckScoping(S);
00064 i = S.find_first_of(")");
00065 std::string stmp = S.substr(1, i-1);
00066 S.erase(0, i+1);
00067 ChanEatFrontWhite(S);
00068
00069 int m, n, start;
00070
00071 m = ChanReadNextInt(stmp);
00072 n = ChanReadNextInt(stmp);
00073 start = ChanReadNextInt(stmp);
00074
00075 int x = start % X;
00076 int y = (start - x) / X;
00077 bool ok = true;
00078
00079 for (int j=y; j<y+n; ++j)
00080 for (int k=x; k<x+m; ++k)
00081 if (mask[(j*X)+k])
00082 ok = false;
00083 else
00084 mask[(j*X)+k] = true;
00085 if (ok) {
00086 ChanViewport l((x*xfrac), ((x+m)*xfrac), (y*yfrac), ((y+n)*yfrac));
00087 L.AddRegion(l);
00088 } else {
00089 nout << "error, region (" << m << " " << n << " " << start
00090 << ") overlaps another. It is being skipped." << endl;
00091 }
00092 }
00093 for (i=0; i<(X*Y); ++i)
00094 if (!mask[i]) {
00095
00096 int x = i % X;
00097 int y = (i - x) / X;
00098 ChanViewport l((x*xfrac), ((x+1)*xfrac), (y*yfrac), ((y+1)*yfrac));
00099 L.AddRegion(l);
00100 }
00101
00102 if (chancfg_cat.is_debug()) {
00103 chancfg_cat->debug() << "parsed a layout called '" << sym << "':" << endl;
00104 chancfg_cat->debug() << " " << L.GetNumRegions() << " regions" << endl;
00105 for (int q=0; q<L.GetNumRegions(); ++q) {
00106 const ChanViewport& v = L[q];
00107 chancfg_cat->debug() << " region #" << q << ": (" << v.left() << ", "
00108 << v.right() << ", " << v.bottom() << ", "
00109 << v.top() << ")" << endl;
00110 }
00111 }
00112 (*LayoutDB)[sym] = L;
00113 }
00114
00115 void ResetLayout() {
00116 if (LayoutDB != (LayoutType *)NULL) {
00117 delete LayoutDB;
00118 }
00119 LayoutDB = new LayoutType;
00120 }
00121
00122 void ParseLayout(istream& is) {
00123 LayoutParseFunctor l;
00124 ChanParse(is, &l);
00125 }