cResourceImage *cFrameBitmap::AddBitmap(iBitmap2D *apSrc) { cResourceImage *pImage=NULL; //source size //+2 because we are gonna have a border to get rid if some antialiasing problems int lSW = apSrc->GetWidth()+2; int lSH = apSrc->GetHeight()+2; //destination size int lDW = mpBitmap->GetWidth(); int lDH = mpBitmap->GetHeight(); cVector2l vPos; bool bFoundEmptyNode = false; bool bFoundNode = false; //Debug int node=0; if(DEBUG_BTREE)Log("**** Image %d *****\n",mlPicCount); //Get the leaves of the tree and search it for a good pos. tRectTreeNodeList lstNodes = mRects.GetLeafList(); tRectTreeNodeListIt it; for(it = lstNodes.begin();it!=lstNodes.end();++it) { if(DEBUG_BTREE)Log("Checking node %d:\n",node++); tRectTreeNode *TopNode = *it; cFBitmapRect* pData = TopNode->GetData(); //Check if the space is free if(pData->mlHandle<0) { if(DEBUG_BTREE)Log("Found free node\n"); bFoundEmptyNode = true; //An empty node was found.. bitmap not full yet. //Check if the Image fits in the rect cRect2l NewRect = cRect2l(pData->mRect.x,pData->mRect.y,lSW, lSH); if(DEBUG_BTREE)Log("Fit: [%d:%d:%d:%d] in [%d:%d:%d:%d]\n", NewRect.x,NewRect.y,NewRect.w,NewRect.h, pData->mRect.x,pData->mRect.y,pData->mRect.w,pData->mRect.h); if(cMath::BoxFit(NewRect, pData->mRect)) { if(DEBUG_BTREE)Log("The node fits!\n"); bFoundNode = true; //If the bitmap fits perfectly add the node without splitting if(MinimumFit(NewRect,pData->mRect)) { if(DEBUG_BTREE)Log("Minimum fit!\n"); pData->mRect = NewRect; pData->mlHandle = 1; } //If there is still space left, make new nodes. else { if(DEBUG_BTREE)Log("Normal fit!\n"); //Insert 2 children for the top node (lower and upper part. tRectTreeNode* UpperNode; //Upper UpperNode = mRects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y, pData->mRect.w,NewRect.h,-2),TopNode, eBinTreeNode_Left); //Lower mRects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y+NewRect.h, pData->mRect.w,pData->mRect.h-NewRect.h,-3),TopNode, eBinTreeNode_Right); //Split the Upper Node into 2 nodes. pData = UpperNode->GetData();//Get the data for the upper node. //Upper split, this is the new bitmap mRects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y, NewRect.w,NewRect.h,2),UpperNode, eBinTreeNode_Left); //Lower split, this is empty mRects.InsertAt(cFBitmapRect(NewRect.x+NewRect.w,NewRect.y, pData->mRect.w-NewRect.w,NewRect.h,-4),UpperNode, eBinTreeNode_Right); } vPos = cVector2l(NewRect.x+1,NewRect.y+1);//+1 for the right pos //Draw 4 times so we get a nice extra border for(int i=0;i<2;i++)for(int j=0;j<2;j++){ apSrc->DrawToBitmap(mpBitmap,cVector2l(NewRect.x+i*2,NewRect.y+j*2)); } //Fix the border a little more: for(int i=-1;i<2;i++)for(int j=-1;j<2;j++) if((i==0 || j==0) && (i!=j)){ apSrc->DrawToBitmap(mpBitmap,cVector2l(NewRect.x+1+i,NewRect.y+1+j)); } //Draw the final apSrc->DrawToBitmap(mpBitmap,cVector2l(NewRect.x+1,NewRect.y+1)); mlPicCount++; mpFrameTexture->SetPicCount(mlPicCount); break; } } } if(bFoundNode) { //Create the image resource pImage = hplNew( cResourceImage, (apSrc->GetFileName(),mpFrameTexture, this, cRect2l(vPos,cVector2l(lSW-2,lSH-2)),//-2 to get the correct size. cVector2l(mpBitmap->GetWidth(),mpBitmap->GetHeight()), mlHandle) ); if(!bFoundEmptyNode) { mbIsFull = true; } mbIsUpdated = true; } /// LAST DEBUG /// if(DEBUG_BTREE) { Log("Current Tree begin:\n"); tRectTreeNodeList lstNodes = mRects.GetNodeList(); tRectTreeNodeListIt it; int node=0; for(it = lstNodes.begin();it!=lstNodes.end();++it) { cRect2l Rect = (*it)->GetData()->mRect; int h = (*it)->GetData()->mlHandle; Log(" %d: [%d:%d:%d:%d]:%d\n",node,Rect.x,Rect.y,Rect.w,Rect.h,h); node++; } Log("Current Tree end:\n"); Log("-----------------\n"); Log("Current Leaves begin:\n"); lstNodes = mRects.GetLeafList(); node=0; for(it = lstNodes.begin();it!=lstNodes.end();++it) { cRect2l Rect = (*it)->GetData()->mRect; int h = (*it)->GetData()->mlHandle; Log(" %d: [%d:%d:%d:%d]: %d\n",node,Rect.x,Rect.y,Rect.w,Rect.h,h); node++; } Log("Current Tree end:\n"); Log("-----------------\n"); } return pImage; }
cResourceImage *cFrameBitmap::AddBitmap(iBitmap2D *a_pSrc) { cResourceImage *pImage=NULL; int lSW = a_pSrc->GetWidth()+2; int lSH = a_pSrc->GetHeight()+2; int lDW = m_pBitmap->GetWidth(); int lDH = m_pBitmap->GetHeight(); cVector2l vPos; bool bFoundEmptyNode = false; bool bFoundNode = false; int node=0; if (DEBUG_BTREE)Log("**** Image %d ****\n", m_lPicCount); tRectTreeNodeList lstNodes = m_Rects.GetLeafList(); tRectTreeNodeListIt it; for (it=lstNodes.begin();it!=lstNodes.end();++it) { if (DEBUG_BTREE)Log("Checking node %d:\n", node++); tRectTreeNode *TopNode = *it; cFBitmapRect *pData = TopNode->GetData(); if (pData->m_lHandle<0) { if (DEBUG_BTREE)Log("Found tree node\n"); bFoundEmptyNode = true; cRectl NewRect = cRectl(pData->m_Rect.x,pData->m_Rect.y,lSW,lSH); if (DEBUG_BTREE)Log("Fit: [%d:%d:%d:%d] in [%d:%d:%d:%d]\n", NewRect.x, NewRect.y, NewRect.w, NewRect.h, pData->m_Rect.x, pData->m_Rect.y, pData->m_Rect.w, pData->m_Rect.h); if (cMath::BoxFit(NewRect,pData->m_Rect)) { if (DEBUG_BTREE)Log("The node fits!\n"); bFoundNode = true; if (MinimumFit(NewRect,pData->m_Rect)) { if (DEBUG_BTREE)Log("Minimum fit!\n"); pData->m_Rect = NewRect; pData->m_lHandle = 1; } else { if (DEBUG_BTREE)Log("Normal fit!\n"); tRectTreeNode *UpperNode; UpperNode = m_Rects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y, pData->m_Rect.w,NewRect.h,-2),TopNode, eBinTreeNode_Left); m_Rects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y+NewRect.h, pData->m_Rect.w,pData->m_Rect.h-NewRect.h,-3),TopNode, eBinTreeNode_Right); pData = UpperNode->GetData(); m_Rects.InsertAt(cFBitmapRect(NewRect.x,NewRect.y, NewRect.w,NewRect.h,2),UpperNode, eBinTreeNode_Left); m_Rects.InsertAt(cFBitmapRect(NewRect.x+NewRect.w,NewRect.y, pData->m_Rect.w-NewRect.w,NewRect.h,-4),UpperNode, eBinTreeNode_Right); } vPos = cVector2l(NewRect.x+1,NewRect.y+1); for (int i=0;i<2;i++) for (int j=0;j<2;j++) { a_pSrc->DrawToBitmap(m_pBitmap, cVector2l(NewRect.x+i*2, NewRect.y+j*2)); } for (int i=0;i<2;i++) { for (int j=0;j<2;j++) if ((i==0 || j==0) && (i!=j)) a_pSrc->DrawToBitmap(m_pBitmap,cVector2l(NewRect.x+1+i, NewRect.y+1+j)); } a_pSrc->DrawToBitmap(m_pBitmap,cVector2l(NewRect.x+1,NewRect.y+1)); m_lPicCount++; m_pFrameTexture->SetPicCount(m_lPicCount); break; } } } if (bFoundNode) { pImage = efeNew(cResourceImage, (a_pSrc->GetFileName(),m_pFrameTexture,this, cRectl(vPos,cVector2l(lSW-2,lSH-2)), cVector2l(m_pBitmap->GetWidth(),m_pBitmap->GetHeight()), m_lHandle)); if (!bFoundEmptyNode) m_bIsFull = true; m_bIsUpdated = true; } if (DEBUG_BTREE) { Log("Current Tree begin:\n"); tRectTreeNodeList lstNodes = m_Rects.GetNodeList(); tRectTreeNodeListIt it; int node=0; for (it=lstNodes.begin();it!=lstNodes.end();++it) { cRectl Rect = (*it)->GetData()->m_Rect; int h = (*it)->GetData()->m_lHandle; Log(" %d: [%d:%d:%d:%d]:%d\n",node,Rect.x,Rect.y,Rect.w,Rect.h,h); node++; } Log("Current Tree end:\n"); Log("-----------------\n"); Log("Current Leaves begin:\n"); lstNodes = m_Rects.GetLeafList(); node=0; for(it=lstNodes.begin();it!=lstNodes.end();++it); { cRectl Rect = (*it)->GetData()->m_Rect; int h = (*it)->GetData()->m_lHandle; Log(" %d: [%d:%d:%d:%d]:%d\n",node,Rect.x,Rect.y,Rect.w,Rect.h,h); node++; } Log("Current Tree end:\n"); Log("-----------------\n"); } return pImage; }