📄 waku.cpp
字号:
return true;
}
return false;
}
bool wakuslot::Processawaku(wakuinterface** presult)
{
if(*presult==NULL)
return false;
if(nCurTotal>0)
{
if(pPWaku->equal(*presult))
{
nCurTotal--;
nTotal--;
return true;
}else
return false;
}
return false;
}
bool wakubag::HasContentToProcess(wakuinterface** presult,bool canprocessbasic)
{
if(nCurTotal==0)
return false;
//if(((*presult)->getheight()==nHeight)&&((*presult)->getwidth()==nWidth))
{
vector< wakuslot* >::iterator iter = wakus.begin();
vector< wakuslot* >::iterator iterend = wakus.end();
if(canprocessbasic)
{
for(;iter!=iterend;++iter)
{
if((*iter)->HasContentToProcess(presult))
return true;
}
}else{
for(;iter!=iterend;++iter)
{
if((*iter)->HasContentToProcess(presult))
{
if((*presult)->getmaxwidth()!=12)//it is a composition waku
return true;
}
}
}
}
return false;
}
bool wakubag::Processawaku(wakuinterface** presult)
{
if(*presult==NULL)
return FALSE;
if(nCurTotal==0)
return false;
if(((*presult)->getheight()==nHeight)&&((*presult)->getwidth()==nWidth))
{
vector< wakuslot* >::iterator iter = wakus.begin();
vector< wakuslot* >::iterator iterend = wakus.end();
for(;iter!=iterend;++iter)
{
if((*iter)->Processawaku(presult))
{
nCurTotal--;
nTotal--;
return true;
}
}
}
return false;
}
BandLine::BandLine(int nset)
{
num = nset;
posuse = new int[nset];
for(int i = 0;i<nset;i++)
posuse[i]=1;
}
BandLine::~BandLine()
{
delete [] posuse;
}
bool BandLine::IsBlankAtPos(int x,int Width)
{
for(int i = x;(i<x+Width)&&(i<num);i++)
{
if(posuse[i]==0)
return false;
}
return true;
}
bool BandLine::HaveBlankPos(int& xpos,int width)
{
int nInit = 0;
for(int i = xpos;i<num;i++)
{
if(posuse[i])
{
nInit++;
if(nInit==width)
{
xpos = i-width+1;
break;
}
}
else{
nInit = 0;
}
}
return (nInit==width);
}
void BandLine::MarkLayout(int nWidth,int xpos)
{
assert(xpos+nWidth<=num);
for(int i = xpos;i<xpos+nWidth;i++)
{
posuse[i] = 0;
}
}
layoutrect::layoutrect(int width,int height,int wscale)
{
nwidth = width;
nheight = height;
nwscale = wscale;
bFull = false;
nremainarea = nwidth*nheight;
pBand = new BandLine*[nheight];
for(int i = 0;i<nheight;i++)
pBand[i] = new BandLine(nwidth);
waku.setheight(nheight);
waku.setwidth(nwidth);
waku.setwidthscale(wscale);
}
layoutrect::~layoutrect()
{
for(int i = 0;i<nheight;i++)
delete pBand[i];
delete [] pBand;
}
bool layoutrect::CanFindSpaceAtPos(int nWidth,int nHeight,int& xpos,int& ypos)
{
bool bFail = false;
bool bSuc = false;
for(int i = ypos;i<nheight;i++)
{
bSuc = false;
if(i+nHeight>nheight)
return false;
while(!bSuc&&pBand[i]->HaveBlankPos(xpos,nWidth))
{
bFail = false;
for(int j = i+1;j<i+nHeight;j++)
{
if(!pBand[j]->IsBlankAtPos(xpos,nWidth))
{
xpos++;
bFail = true;
break;
}
}
if(!bFail)
bSuc = true;
}
if(bSuc)
{
ypos=i;
break;
}else{//reset xpos for next line
xpos = 0;
}
}
return bSuc;
}
bool layoutrect::InitSpace(int nWidth,int nHeight,int& xpos,int& ypos)
{
ypos = 0;
xpos = 0;
bool result = false;
if(!policystatus.rightpreference)
{
for(int i = ypos;i<nheight;i++)
{
if(pBand[i]->IsBlankAtPos(xpos,nWidth))
break;
}
if(i<nheight)
{
ypos = i;
result = CanFindSpaceAtPos(nWidth,nHeight,xpos,ypos);
if(xpos!=0)
result = false;
}
}else {
if(nWidth<=nwidth){
xpos = nwidth-nWidth;
for(int i = ypos;i<nheight;i++)
{
if(pBand[i]->IsBlankAtPos(xpos,nWidth))
break;
}
if(i<nheight)
{
ypos = i;
result = CanFindSpaceAtPos(nWidth,nHeight,xpos,ypos);
}
}
}
if(!result)
{
ypos = 0;
xpos = 0;
result = CanFindSpaceAtPos(nWidth,nHeight,xpos,ypos);
}
return result;
}
bool layoutrect::ValidateSpace(int nWidth,int nHeight,int& xpos1,int& ypos1)
{
if(nHeight==1||policystatus.ignorevalidate||(nHeight==15))
return true;
int ypos = ypos1+nHeight;
bool begoodup = false;
if(ypos>nheight)
return false;
if(ypos!=nheight)
{
if((ypos<nheight)&&(ypos+1>=nheight))
return false;
bool bBlank1 = pBand[ypos]->IsBlankAtPos(xpos1,nWidth);
bool bBlank2 = pBand[ypos+1]->IsBlankAtPos(xpos1,nWidth);
if(!(bBlank1&&bBlank2||(!bBlank1)))
{
return false;
}else{
if(!bBlank1&&!bBlank2)
{
for(int i = 1;i<nWidth;i++)
{
if(pBand[ypos]->IsBlankAtPos(xpos1,i))
return false;
if(pBand[ypos+1]->IsBlankAtPos(xpos1,i))
return false;
}
}
}
}
ypos = ypos1;
if(ypos==1)
return FALSE;
if(ypos>1)
{
bool bBlank1 = pBand[ypos-1]->IsBlankAtPos(xpos1,nWidth);
bool bBlank2 = pBand[ypos-2]->IsBlankAtPos(xpos1,nWidth);
if(!(bBlank1&&bBlank2||(!bBlank1)))
{
return false;
}else{
if(!bBlank1&&!bBlank2)
{
for(int i = 1;i<nWidth;i++)
{
if(pBand[ypos-1]->IsBlankAtPos(xpos1,i))
return false;
if(pBand[ypos-2]->IsBlankAtPos(xpos1,i))
return false;
}
}
}
}
return true;
}
bool layoutrect::CanAdjustPos(int nWidth,int nHeight,int& xpos,int& ypos)
{
xpos++;
return CanFindSpaceAtPos(nWidth,nHeight,xpos,ypos);
}
bool layoutrect::CanLayoutinner(int nWidth,int nHeight,int& xpos,int& ypos)
{
if(nremainarea<nWidth*nHeight)
return false;
bool be_y_init = false;
if(InitSpace(nWidth,nHeight,xpos,ypos))
{
bool bMoreTry = true;
while(bMoreTry)
{
if(ValidateSpace(nWidth,nHeight,xpos,ypos))
return true;
if(!be_y_init)
{
be_y_init = true;
xpos = 0;
ypos = 0;
bMoreTry = CanFindSpaceAtPos(nWidth,nHeight,xpos,ypos);
}else
bMoreTry = CanAdjustPos(nWidth,nHeight,xpos,ypos);
}
}
return false;
}
bool layoutrect::CanLayout(int nWidth,int nHeight,int& xpos,int& ypos)
{
bool bresult = CanLayoutinner(nWidth, nHeight, xpos, ypos);
if(!bresult&&!policystatus.rightpreference)
{
policystatus.rightpreference = true;
bresult = CanLayoutinner(nWidth, nHeight, xpos, ypos);
policystatus.rightpreference = false;
}
return bresult;
}
void layoutrect::MarkLayout(int nWidth,int nHeight,int& xpos,int& ypos)
{
assert(ypos+nHeight<=nheight);
for(int i = ypos;i<ypos+nHeight;i++)
pBand[i]->MarkLayout(nWidth,xpos);
}
bool layoutrect:: LayoutAWaku(wakuinterface* pwaku)
{
int xpos,ypos;
xpos = ypos = 0;
int nWidth = pwaku->getwidth();
int nHeight = pwaku->getheight();
if(CanLayout(nWidth,nHeight,xpos,ypos))
{
MarkLayout(nWidth,nHeight,xpos,ypos);
nremainarea-=(nWidth*nHeight);
wakuinterface* pcopy = pwaku->duplicate();
pcopy->setpos(xpos,ypos);
waku.AddWaku(pcopy);
if(nremainarea==0)
bFull = true;
return true;
}
return false;
}
bool layoutrect::BeFullOfWaku()
{
return bFull;
}
void layoutrect::SetBeFullOfWaku(bool bSet)
{
bFull = bSet;
}
int layoutrect::RemainArea()
{
return nremainarea;
}
void layoutrect::OutputResult(ofstream& out,bool beps)
{
if(beps)
{
out<<"/savet save def"<<endl;
out<<"gsave"<<endl;
out<<"0.9 setgray 0 0 translate 0 0 moveto 0 0 12 16 rectfill"<<endl;
out<<"grestore"<<endl;
out<<"gsave"<<endl;
waku.sortwaku();
waku.OutputResult(out,0,0,beps);
out<<"grestore"<<endl;
//out<<" 0 setgray 3 0 moveto 3 16 lineto 6 0 moveto 6 16 lineto 9 0 moveto 9 16 lineto stroke "<<endl;
//out<<" 0 setgray 0 2 moveto 12 2 lineto 0 4 moveto 12 4 lineto 0 6 moveto 12 6 lineto stroke "<<endl;
//out<<" 0 setgray 0 8 moveto 12 8 lineto 0 10 moveto 12 10 lineto 0 12 moveto 12 12 lineto stroke "<<endl;
//out<<" 0 setgray 0 14 moveto 12 14 lineto stroke "<<endl;
out<<" showpage"<<endl;
out<<"savet restore"<<endl;
}else{
waku.OutputResult(out,0,0,beps);
out<<"pageend"<<endl;
}
}
void layout::getlayoutrect(vector< layoutrect* >& result)
{
if(Pages.begin()!=Pages.end())
{
result.resize(Pages.size());
copy(Pages.begin(),Pages.end(),result.begin());
}
}
layout::layout(int height,int width,int hbarrier,int wbarrier)
{
nHeight =height;
nWidth = width;
nheightbarrier = hbarrier;
nwidthbarrier = wbarrier;
}
layout::~layout()
{
vector< layoutrect* >::iterator iter = Pages.begin();
vector< layoutrect* >::iterator iterend = Pages.end();
for(;iter!=iterend;++iter)
delete (*iter);
}
void AddwakuTobags(wakuinterface* pwaku,wakubags& Wakus,int num = 1,bool b4pattern=false)
{
wakuslot Slot(b4pattern ? 4:pwaku->getwidth(),pwaku->getheight(),pwaku->getwidthscale(),num,pwaku);
vector< wakuslot* > vecwaku;
vecwaku.push_back(&Slot);
wakubag bag;
bag.setwidth(b4pattern ? 4:pwaku->getwidth());
bag.setheight(pwaku->getheight());
bag.addwakuslot(vecwaku);
Wakus.addwakubag(&bag);
}
bool layout:: LayoutWakus(wakubags& Wakus,bool onlyfull,bagsvistinterface& vistor)
{
ncurpagenum = 0;
wakuinterface* pwaku = NULL;
bool bLeftPageForlayout = true;
layoutrect* playoutrect = NULL;
bool bhascont = true;
int nPagenum = 0;
bool set = false;
int HeightReserve = nHeight;
int ncurrelayoutpage = 0;
int nlastarea = 0;
bool bemptypageerror = false;
if(!onlyfull)
policystatus.ignorevalidate = false;
while(bLeftPageForlayout&&bhascont)
{
bLeftPageForlayout = false;
if(playoutrect==NULL)
{
vistor.beginonepage(nHeight);
if(Wakus.HasContentToProcess(vistor))
{
pwaku = vistor.getwaku();
if(pwaku->getheight()<nheightbarrier)
break;
if(pwaku->getwidth()<nwidthbarrier)
break;
}
playoutrect = new layoutrect(nWidth, nHeight,Wakus.getwscale());
//playoutrect = new layoutrect(nWidth,(nHeight==16)? nHeight-nPagenum%3 : nHeight,Wakus.getwscale());
}
if(!playoutrect->BeFullOfWaku())
{
bLeftPageForlayout = true;
if(Wakus.HasContentToProcess(vistor))
{
pwaku = vistor.getwaku();
bhascont = true;
if(playoutrect->LayoutAWaku(pwaku))
{
Wakus.Processawaku(vistor);
vistor.layoutstatusoflastwaku(true);
}else{
vistor.layoutstatusoflastwaku(false);
}
}else{
bhascont = false;
}
}
if(playoutrect->BeFullOfWaku()||((!onlyfull)&&(!bhascont)))
{
if(playoutrect->BeFullOfWaku())
{
if(!onlyfull)
policystatus.ignorevalidate = false;
Pages.push_back(playoutrect);
nPagenum++;
ncurpagenum++;
ncurrelayoutpage = 0;
nHeight = HeightReserve;
vistor.endpage(true);
//cout<<nPagenum<<endl;
}else{
//cout<<ncurrelayoutpage<<endl;
/*
if(!bemptypageerror&&((ncurrelayoutpage<2)))
{
nHeight = HeightReserve-1;
if(ncurrelayoutpage==1)
{
if(!onlyfull)
policystatus.ignorevalidate = true;
nHeight = HeightReserve;
}
ncurrelayoutpage++;
compositewaku* ptmpwaku = playoutrect->getwaku();
if(!ptmpwaku->isempty())
{
vector< wakuinterface* > tmpvec;
ptmpwaku->getwakus(tmpvec);
vector< wakuinterface* >::iterator iter = tmpvec.begin();
vector< wakuinterface* >::iterator iterend = tmpvec.end();
for(;iter!=iterend;++iter)
{
(*iter)->setpos(0,0);
{
if((*iter)->getmaxwidth()==12)
++nfullcolumnleft;
AddwakuTobags((*iter)->duplicate(),Wakus,1);
}
}
delete playoutrect;
}else{
delete playoutrect;
}
vistor.endpage(false);
}else*/
{
if(playoutrect->getwaku()->gettotalscaledarea()>0)
{
Pages.push_back(playoutrect);
vistor.endpage(true);
nPagenum++;
ncurpagenum++;
}else{
vistor.endpage(false);
delete playoutrect;
bemptypageerror = true;
}
ncurrelayoutpage = 0;
nHeight = HeightReserve;
nlastarea = 0;
}
}
playoutrect = NULL;
vistor.beginonepage(nHeight);
bhascont = true;
if(!Wakus.HasContentToProcess(vistor))
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -