// Show 		 - Show the titletip if needed
// rectTitle	 - The rectangle within which the original 
//				    title is constrained - in client coordinates
// lpszTitleText - The text to be displayed
// xoffset		 - Number of pixel that the text is offset from
//				   left border of the cell
void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/,
                     LPRECT lpHoverRect /*=NULL*/,
                     LPLOGFONT lpLogFont /*=NULL*/)
{
	ASSERT( ::IsWindow( GetSafeHwnd() ) );

    if (rectTitle.IsRectEmpty())
        return;

    m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;

	m_pParentWnd->ClientToScreen( m_rectHover );
    ScreenToClient( m_rectHover );

	// If titletip is already displayed, don't do anything.
	if( IsWindowVisible() ) 
		return;

	// Do not display the titletip is app does not have focus
	if( GetFocus() == NULL )
		return;

	// Define the rectangle outside which the titletip will be hidden.
	// We add a buffer of one pixel around the rectangle
	m_rectTitle.top    = -1;
	m_rectTitle.left   = -xoffset-1;
	m_rectTitle.right  = rectTitle.Width()-xoffset;
	m_rectTitle.bottom = rectTitle.Height()+1;

	// Determine the width of the text
	m_pParentWnd->ClientToScreen( rectTitle );

	CClientDC dc(this);
	CString strTitle = _T("");
    strTitle += _T(" ");
    strTitle += lpszTitleText; 
    strTitle += _T(" ");

	CFont font, *pOldFont = NULL;
    if (lpLogFont)
    {
        font.CreateFontIndirect(lpLogFont);
	    pOldFont = dc.SelectObject( &font );
    }
    else
    {
        // use same font as ctrl
	    pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
    }

	CSize size = dc.GetTextExtent( strTitle );

    TEXTMETRIC tm;
    dc.GetTextMetrics(&tm);
    size.cx += tm.tmOverhang;

	CRect rectDisplay = rectTitle;
	rectDisplay.left += xoffset;
	rectDisplay.right = rectDisplay.left + size.cx + xoffset;
    
    // Do not display if the text fits within available space
    // Show the titletip
    SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top, 
        rectDisplay.Width(), rectDisplay.Height(), 
        SWP_SHOWWINDOW|SWP_NOACTIVATE );

    CRect client;
    GetClientRect(&client);
    
    if(!m_bIsTransparent)
    {
        CBrush br(TIPS_BACKCOLOR);
        dc.FillRect(&client,&br);
        br.DeleteObject();
    }

    if(m_bHasBorder)
    {
        CBrush br(RGB(0,0,0));
        dc.FrameRect(&client,&br);
        br.DeleteObject();
    }

    dc.SetBkMode( TRANSPARENT );
    dc.TextOut( 0, 0, strTitle );
    SetCapture();
    
    dc.SelectObject( pOldFont );
}
Exemple #2
0
void Multiplexer::OnBlockHeader(Connection& s, net::Buffer&& buffer) {

    // received invalid Buffer: the connection has closed?
    if (!buffer.IsValid()) return;

    StreamBlockHeader header;
    net::BufferReader br(buffer);
    header.ParseHeader(br);

    // received stream id
    StreamId id = header.stream_id;
    size_t local_worker = header.receiver_local_worker_id;
    size_t sender_worker_rank =
        header.sender_rank * num_workers_per_host_ + header.sender_local_worker_id;

    if (header.magic == MagicByte::CAT_STREAM_BLOCK)
    {
        CatStreamPtr stream = GetOrCreateCatStream(id, local_worker);

        if (header.IsEnd()) {
            sLOG << "end of stream on" << s << "in CatStream" << id
                 << "from worker" << sender_worker_rank;

            stream->OnCloseStream(sender_worker_rank);

            AsyncReadBlockHeader(s);
        }
        else {
            sLOG << "stream header from" << s << "on CatStream" << id
                 << "from worker" << sender_worker_rank;

            ByteBlockPtr bytes = ByteBlock::Allocate(header.size, block_pool_);

            dispatcher_.AsyncRead(
                s, bytes,
                [this, header, stream, bytes](Connection& s) {
                    OnCatStreamBlock(s, header, stream, bytes);
                });
        }
    }
    else if (header.magic == MagicByte::MIX_STREAM_BLOCK)
    {
        MixStreamPtr stream = GetOrCreateMixStream(id, local_worker);

        if (header.IsEnd()) {
            sLOG << "end of stream on" << s << "in MixStream" << id
                 << "from worker" << sender_worker_rank;

            stream->OnCloseStream(sender_worker_rank);

            AsyncReadBlockHeader(s);
        }
        else {
            sLOG << "stream header from" << s << "on MixStream" << id
                 << "from worker" << sender_worker_rank;

            ByteBlockPtr bytes = ByteBlock::Allocate(header.size, block_pool_);

            dispatcher_.AsyncRead(
                s, bytes,
                [this, header, stream, bytes](Connection& s) {
                    OnMixStreamBlock(s, header, stream, bytes);
                });
        }
    }
    else {
        die("Invalid magic byte in BlockHeader");
    }
}
void MY_UI_Too::Renderer::DrawTexturedRect_Clip(const MY_UI_Too::Interfaces::ITexture* pTexture,const  MY_UI_Too::Utilities::UVs& uvs, const MY_UI_Too::Utilities::Rect rect,  const MY_UI_Too::Utilities::Color color_tl, const MY_UI_Too::Utilities::Color color_tr, const MY_UI_Too::Utilities::Color color_bl, const MY_UI_Too::Utilities::Color color_br, bool drawnow){
	if(!SetTexture(pTexture, drawnow)) return;
	assert(!ClipRects.empty());
	Utilities::Point tl(rect.left, rect.top);
	Utilities::Point tr(rect.left + rect.width, rect.top);
	Utilities::Point bl(rect.left, rect.top + rect.height);
	Utilities::Point br(rect.left + rect.width, rect.top + rect.height);
	// if all the points are not within the cliprect, dont draw it
	bool brin = ClipRects.back().Intersect(br);
	bool trin = ClipRects.back().Intersect(tr);

	bool blin = ClipRects.back().Intersect(bl);
	bool tlin = ClipRects.back().Intersect(tl);

	if( (!brin) & (!trin) & (!blin) & (!tlin)) return;// all points are outside the cliprect


	float left= static_cast<float>(rect.left);
	float top = static_cast<float>(rect.top);
	float width = static_cast<float>(rect.width);
	float right = width + left;
	float height = static_cast<float>(rect.height);
	float bottom = height + top;
	// resize the buffer if needed
	if(Draw_States[ Draw_State_Index ].Verts.size() <= 4 + Draw_States[ Draw_State_Index ].NumVerts ) Draw_States[ Draw_State_Index ].Verts.resize(Draw_States[ Draw_State_Index ].Verts.size() + 200);
	if( (brin) & (trin) & (blin) & (tlin)){// all points are fully contained inside the cliprect

		AddVert( left, top,					uvs.u1, uvs.v1, color_tl );
		AddVert( right, top,				uvs.u2, uvs.v1, color_tr );
		AddVert( left, bottom,				uvs.u1, uvs.v2, color_bl );
		AddVert( right, bottom,				uvs.u2, uvs.v2, color_br );


	} else {// this means the rect is partially in the clip region. Use the cpu to clip it

		Utilities::Rect& r = ClipRects.back();
		float newleft= static_cast<float>(Utilities::Clamp<int>(rect.left, r.left, r.left + r.width));
		float newtop = static_cast<float>(Utilities::Clamp<int>(rect.top, r.top, r.top + r.height));
		float newright = static_cast<float>(Utilities::Clamp<int>(rect.width + rect.left, r.left, r.left + r.width));
		float newbottom = static_cast<float>(Utilities::Clamp<int>(rect.height + rect.top, r.top, r.top + r.height));

		float difleft = newleft - left;
		float diftop = newtop - top;
		float difright = newright - right;
		float difbottom = newbottom - bottom;

		difleft /= width;
		diftop /= height;
		difright /= width;
		difbottom /= height;

		float u1 = uvs.u1;
		float v1 = uvs.v1;
		float u2 = uvs.u2;
		float v2 = uvs.v2;

		float uwidth = u2 - u1;
		float vheight = v2 - v1;

		u1 = u1 + (uwidth*difleft);
		u2 = u2 + (uwidth*difright);
		v1 = v1 + (vheight*diftop);
		v2 = v2 + (vheight*difbottom);

		AddVert( newleft, newtop,					u1, v1, color_tl );
		AddVert( newright, newtop,					u2, v1, color_tr );
		AddVert( newleft, newbottom,				u1, v2, color_bl );
		AddVert( newright, newbottom,				u2, v2, color_br );

	}
}
Exemple #4
0
void CSpiroView::OnDraw(CDC* pDC)
{
	ENSURE(pDC != NULL);
	
	CPaintDC*	pDCPaint;
	int			nWidthClip(0);  // Initialize to avoid compiler warnings.
	int			nHeightClip(0);  // Initialize to avoid compiler warnings.
	CRect		rectClip;
	CSpiroRect	rectLogClip;
	
	if (!pDC->IsPrinting())
	{
		ASSERT(pDC->IsKindOf(RUNTIME_CLASS(CPaintDC)));
		pDCPaint = (CPaintDC*)pDC;
		rectClip = pDCPaint->m_ps.rcPaint;
		rectLogClip = rectClip;
		pDC->DPtoLP(&rectLogClip);   // this will be the clip rectangle which includes the zoom factor in it
		nWidthClip = rectLogClip.Width();
		nHeightClip = rectLogClip.Height();
		// Prepare a memory DC to draw on
		if (nWidthClip <= 0 || nHeightClip >= 0)  // the clipping region is empty
			return;  // nothing to draw in this case
	}

	g_pView = this;
	CSpiroDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CDC* pDCUse = pDC;
	int nSavedDC(0);  // Initialized to avoid compiler warnings.

	CRgn*	prgnWheel = NULL;

	if (!pDC->IsPrinting())
	{
		if (m_pDCMem == NULL)
		{
			m_pDCMem = new CDC();
			ASSERT(m_pDCMem != NULL);
			VERIFY(m_pDCMem->CreateCompatibleDC(pDC));
			m_pDCMem->SetMapMode(MM_SPIRO);
		}

		int cxClip = rectClip.Width();
		int cyClip = rectClip.Height();
		ASSERT(cxClip > 0 && cyClip >0);

		if (m_pBitmap == NULL)
			m_pBitmap = new CBitmap();

		if (cxClip > m_sizeBitmap.cx || cyClip > m_sizeBitmap.cy)
		{
			if (m_pbitmapOld != NULL)
			{
				m_pDCMem->SelectObject(m_pbitmapOld);
				m_pBitmap->DeleteObject();
			}

			VERIFY(m_pBitmap->CreateCompatibleBitmap(pDC, cxClip, cyClip));
			m_pbitmapOld  = m_pDCMem->SelectObject(m_pBitmap);
			m_sizeBitmap.cx = cxClip;
			m_sizeBitmap.cy = cyClip;
		}

		CPoint ptViewportOrg = pDC->GetViewportOrg();
		ptViewportOrg.x -= rectClip.left;
		ptViewportOrg.y -= rectClip.top;
		m_pDCMem->SetViewportOrg(ptViewportOrg);
		m_pDCMem->SetWindowOrg(pDC->GetWindowOrg());

		CSpiroRect  rectDoc(rectLogClip);
		CSpiroRect	rectOut(rectDoc);  // strip to the right of the doc (vertical strip)

		int cx = pDoc->m_sizeExtent.cx * m_nZoomNumer / m_nZoomDenom;
		CBrush	br(GetSysColor(COLOR_3DLIGHT));

		if (rectDoc.right > cx)  // paint vertical strip
		{
			rectOut.left = cx;
			rectDoc.right = cx;
			m_pDCMem->FillRect(&rectOut, &br);
		}

		if (rectDoc.bottom < 0)
		{
			rectOut.SetRect(rectDoc.left, 0, cx, rectDoc.bottom);
			m_pDCMem->FillRect(&rectOut, &br);
			rectDoc.bottom = 0;
		}

		CBrush brush(GetSysColor(COLOR_WINDOW));
		m_pDCMem->FillRect(&rectDoc, &brush);

		pDCUse = m_pDCMem;
		nSavedDC = pDCUse->SaveDC();
		pDCUse->IntersectClipRect(0, pDoc->m_sizeExtent.cy * m_nZoomNumer / m_nZoomDenom, cx, 0);

		if (m_pWheel != NULL)
		{
			prgnWheel = new CRgn();
			m_pWheel->GetLogPieceRgn(prgnWheel, m_nZoomNumer, m_nZoomDenom);
		}
	}


	// draw the current figure
	pDoc->m_pFigureCurrent->Draw(pDCUse, m_nZoomNumer, m_nZoomDenom
												, prgnWheel, &rectLogClip);

	// draw all the other figures
	INT_PTR nLast = pDoc->m_arrPFigures.GetUpperBound();
	CFigure* pFig;
	for (int i = 0; i <= nLast; i++)
	{
		pFig = (CFigure*)pDoc->m_arrPFigures.GetAt(i);
		pFig->Draw(pDCUse, m_nZoomNumer, m_nZoomDenom, prgnWheel, &rectLogClip);
	}

	delete prgnWheel;

	if (!pDC->IsPrinting())
	{

		pDCUse->RestoreDC(nSavedDC);

		if (m_pAnchor != NULL) 
			m_pAnchor->Draw(m_pDCMem, m_nZoomNumer, m_nZoomDenom);

		if (m_pWheel != NULL)
			m_pWheel->Draw(m_pDCMem, m_nZoomNumer, m_nZoomDenom);

		// now transfer the information in the memory DC to the device DC
		VERIFY(pDC->BitBlt(rectLogClip.left, rectLogClip.top, nWidthClip, nHeightClip, 
													pDCUse, rectLogClip.left, rectLogClip.top, SRCCOPY));

	}
}
/*
通知自绘的消息入口。
流程:
1、CDDS_PREPAINT 开始自绘,如果 返回 CDRF_DODEFAULT,则 CListCtrl 自行绘制。
	如果不存在内存dc,bmp,则创建之,用于绘制。
	或者在 OnEraseBkgndCustom 中创建。

2、CDDS_ITEMPREPAINT,绘制每个 Item。

3、CDDS_POSTPAINT,绘制结束。
	将内存dc,bmp中的数据拷贝到实际dc中,并删除内存dc,bmp。
*/
void CxResLibImgList::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
static const DWORD CDDS_SUBITEMPREPAINT = (DWORD)(CDDS_ITEMPREPAINT | CDDS_SUBITEM);
static const DWORD CDDS_SUBITEMPOSTPAINT = (CDDS_ITEMPOSTPAINT | CDDS_SUBITEM);

	static int nDrawCount = 0;
	LPNMLVCUSTOMDRAW lplvcd = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	//if (lplvcd == NULL) return;

	switch(lplvcd->nmcd.dwDrawStage)
	{
	//整个控件的绘制循环开始前。
	//如果此处返回 CDRF_DODEFAULT,控件将自己绘制自己,不会再收到任何通知。
	case CDDS_PREPAINT:
		{
			if (m_pBmpCanvas != NULL || m_pGraphics != NULL)
			{
				delete m_pGraphics; m_pGraphics = NULL;
				delete m_pBmpCanvas; m_pBmpCanvas = NULL;
			}

			if (m_pBmpCanvas == NULL && m_pGraphics == NULL)
			{
				CRect rc;
				GetClientRect(&rc);
				m_pBmpCanvas = new Bitmap(rc.Width(), rc.Height(), PixelFormat32bppARGB);
				m_pGraphics = new Graphics(m_pBmpCanvas);
				//设定透明模式,和点阵模式,如果不设定会出现毛边,造成图形边界不是很平滑
				m_pGraphics->SetSmoothingMode(SmoothingModeAntiAlias);
				m_pGraphics->SetPixelOffsetMode(PixelOffsetModeHighQuality);
				//m_pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias);
				//擦除背景
				RectF rcf((float)rc.left, (float)rc.top, (float)rc.Width(), (float)rc.Height());
				SolidBrush br(m_crCanvasBk);
				m_pGraphics->FillRectangle(&br, rcf);

				nDrawCount = 0;

				//ZTools::WriteZToolsFormatLog( "CxResLibImgList::OnNMCustomdraw %s", "创建Canvas\r\n" );
			}
		}
		
		*pResult = CDRF_NOTIFYITEMDRAW //Item 绘制前后,通知
			| CDRF_NOTIFYPOSTPAINT //整个控件绘制完成后,通知
			| CDRF_NOTIFYPOSTERASE //擦除之后,通知。完全不起作用,个人理解,可以通过实现 OnEraseBkgnd 替代。
			| CDRF_NOTIFYSUBITEMDRAW //子Item 绘制前后,通知
			; 
		break;

	case  CDDS_POSTPAINT: //整个控件的绘制循环完成。
		{
			if (m_pBmpCanvas != NULL && m_pGraphics != NULL )
			{
				BOOL bDraw = TRUE;
				if ( m_vImg.size() > 1 && nDrawCount <= 1 )
				{
					bDraw = FALSE;
				}
				else
				{
					//xp下,当有其他窗口档在最后一个组件上时,右侧区域不被绘制
					DWORD dwBakSpec = lplvcd->nmcd.dwItemSpec;
					for (int i=0; i<(int)m_vImg.size(); i++)
					{
						lplvcd->nmcd.dwItemSpec = i;
						OnItemPaint(lplvcd);
					}
					lplvcd->nmcd.dwItemSpec = dwBakSpec;
				}
				//if ( bDraw )
				{
					Graphics g(lplvcd->nmcd.hdc);
					CachedBitmap cachedBmp(m_pBmpCanvas, &g);
					g.DrawCachedBitmap(&cachedBmp, 0, 0);
					g.ReleaseHDC(lplvcd->nmcd.hdc);
				}

				delete m_pGraphics; m_pGraphics = NULL;
				delete m_pBmpCanvas; m_pBmpCanvas = NULL;

				nDrawCount = 0;

				//ZTools::WriteZToolsFormatLog( "CxResLibImgList::OnNMCustomdraw %s", "拷贝Canvas到DC\r\n" );
			}
		}

		*pResult = CDRF_DODEFAULT;
		break;

	case CDDS_PREERASE:      // Before the erase cycle begins
	case CDDS_POSTERASE:     // After the erase cycle is complete
	case CDDS_ITEMPREERASE:  // Before an item is erased
	case CDDS_ITEMPOSTERASE: // After an item has been erased
		// these are not handled now, but you might like to do so in the future
		*pResult = CDRF_DODEFAULT;
		break;

	//Before an item is drawn.
	case CDDS_ITEMPREPAINT: // Item 绘制前
		if ( !OnItemPaint(lplvcd) )
			*pResult = CDRF_DODEFAULT; //失败
		else
		{
			//成功
			nDrawCount++;
			*pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NOTIFYPOSTPAINT | CDRF_SKIPDEFAULT;
		}
		//ZTools::WriteZToolsFormatLog( "CxResLibImgList::OnNMCustomdraw %s", "OnItemPaint\r\n" );
		break;

	//After an item is drawn.
	case CDDS_ITEMPOSTPAINT: //Item 绘制完成后
		//*pResult = CDRF_DODEFAULT;
		//*pResult = CDRF_SKIPDEFAULT;
		*pResult = CDRF_NOTIFYSUBITEMDRAW;
		break;
	
	//Before an sub-item is drawn.
	case CDDS_SUBITEMPREPAINT: //SubItem 绘制前
		*pResult = CDRF_DODEFAULT;
		break;
	////after an sub-item is drawn.
	case CDDS_SUBITEMPOSTPAINT: //SubItem 绘制完成后
		*pResult = CDRF_DODEFAULT;
		break;
	}

	//*pResult = 0; 通过返回值控制绘制的各个阶段
}
inline void MacroAssembler::ba( Label& L ) {
  br(always, false, pt, L);
}
Exemple #7
0
VtableStub* VtableStubs::create_itable_stub(int itable_index) {
  const int code_length = VtableStub::pd_code_size_limit(false);
  VtableStub* s = new(code_length) VtableStub(false, itable_index);
  // Can be NULL if there is no free space in the code cache.
  if (s == NULL) {
    return NULL;
  }

  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

  assert(VtableStub::receiver_location() == R0->as_VMReg(), "receiver expected in R0");

  // R0-R3 / R0-R7 registers hold the arguments and cannot be spoiled
  const Register Rclass  = AARCH64_ONLY(R9)  NOT_AARCH64(R4);
  const Register Rlength = AARCH64_ONLY(R10)  NOT_AARCH64(R5);
  const Register Rscan   = AARCH64_ONLY(R11) NOT_AARCH64(R6);
  const Register tmp     = Rtemp;

  assert_different_registers(Ricklass, Rclass, Rlength, Rscan, tmp);

  // Calculate the start of itable (itable goes after vtable)
  const int scale = exact_log2(vtableEntry::size_in_bytes());
  address npe_addr = __ pc();
  __ load_klass(Rclass, R0);
  __ ldr_s32(Rlength, Address(Rclass, Klass::vtable_length_offset()));

  __ add(Rscan, Rclass, in_bytes(Klass::vtable_start_offset()));
  __ add(Rscan, Rscan, AsmOperand(Rlength, lsl, scale));

  // Search through the itable for an interface equal to incoming Ricklass
  // itable looks like [intface][offset][intface][offset][intface][offset]
  const int entry_size = itableOffsetEntry::size() * HeapWordSize;
  assert(itableOffsetEntry::interface_offset_in_bytes() == 0, "not added for convenience");

  Label loop;
  __ bind(loop);
  __ ldr(tmp, Address(Rscan, entry_size, post_indexed));
#ifdef AARCH64
  Label found;
  __ cmp(tmp, Ricklass);
  __ b(found, eq);
  __ cbnz(tmp, loop);
#else
  __ cmp(tmp, Ricklass);  // set ZF and CF if interface is found
  __ cmn(tmp, 0, ne);     // check if tmp == 0 and clear CF if it is
  __ b(loop, ne);
#endif // AARCH64

  assert(StubRoutines::throw_IncompatibleClassChangeError_entry() != NULL, "Check initialization order");
#ifdef AARCH64
  __ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, tmp);
  __ bind(found);
#else
  // CF == 0 means we reached the end of itable without finding icklass
  __ jump(StubRoutines::throw_IncompatibleClassChangeError_entry(), relocInfo::runtime_call_type, noreg, cc);
#endif // !AARCH64

  // Interface found at previous position of Rscan, now load the method oop
  __ ldr_s32(tmp, Address(Rscan, itableOffsetEntry::offset_offset_in_bytes() - entry_size));
  {
    const int method_offset = itableMethodEntry::size() * HeapWordSize * itable_index +
      itableMethodEntry::method_offset_in_bytes();
    __ add_slow(Rmethod, Rclass, method_offset);
  }
  __ ldr(Rmethod, Address(Rmethod, tmp));

  address ame_addr = __ pc();

#ifdef AARCH64
  __ ldr(tmp, Address(Rmethod, Method::from_compiled_offset()));
  __ br(tmp);
#else
  __ ldr(PC, Address(Rmethod, Method::from_compiled_offset()));
#endif // AARCH64

  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
                  itable_index, p2i(s->entry_point()),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // FIXME ARM: need correct 'slop' - below is x86 code
  // shut the door on sizing bugs
  //int slop = 8;  // 32-bit offset is this much larger than a 13-bit one
  //assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {

  OopMapSet* oop_maps = NULL;
  // for better readability
  const bool must_gc_arguments = true;
  const bool dont_gc_arguments = false;

  // stub code & info for the different stubs
  switch (id) {
    case forward_exception_id:
      {
        // we're handling an exception in the context of a compiled
        // frame.  The registers have been saved in the standard
        // places.  Perform an exception lookup in the caller and
        // dispatch to the handler if found.  Otherwise unwind and
        // dispatch to the callers exception handler.

        oop_maps = new OopMapSet();
        OopMap* oop_map = generate_oop_map(sasm, true);

        // transfer the pending exception to the exception_oop
        __ ld_ptr(G2_thread, in_bytes(JavaThread::pending_exception_offset()), Oexception);
        __ ld_ptr(Oexception, 0, G0);
        __ st_ptr(G0, G2_thread, in_bytes(JavaThread::pending_exception_offset()));
        __ add(I7, frame::pc_return_offset, Oissuing_pc);

        generate_handle_exception(sasm, oop_maps, oop_map);
        __ should_not_reach_here();
      }
      break;

    case new_instance_id:
    case fast_new_instance_id:
    case fast_new_instance_init_check_id:
      {
        Register G5_klass = G5; // Incoming
        Register O0_obj   = O0; // Outgoing

        if (id == new_instance_id) {
          __ set_info("new_instance", dont_gc_arguments);
        } else if (id == fast_new_instance_id) {
          __ set_info("fast new_instance", dont_gc_arguments);
        } else {
          assert(id == fast_new_instance_init_check_id, "bad StubID");
          __ set_info("fast new_instance init check", dont_gc_arguments);
        }

        if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
            UseTLAB && FastTLABRefill) {
          Label slow_path;
          Register G1_obj_size = G1;
          Register G3_t1 = G3;
          Register G4_t2 = G4;
          assert_different_registers(G5_klass, G1_obj_size, G3_t1, G4_t2);

          // Push a frame since we may do dtrace notification for the
          // allocation which requires calling out and we don't want
          // to stomp the real return address.
          __ save_frame(0);

          if (id == fast_new_instance_init_check_id) {
            // make sure the klass is initialized
            __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
            __ cmp(G3_t1, instanceKlass::fully_initialized);
            __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
            __ delayed()->nop();
          }
#ifdef ASSERT
          // assert object can be fast path allocated
          {
            Label ok, not_ok;
          __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
          __ cmp(G1_obj_size, 0);  // make sure it's an instance (LH > 0)
          __ br(Assembler::lessEqual, false, Assembler::pn, not_ok);
          __ delayed()->nop();
          __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
          __ br(Assembler::zero, false, Assembler::pn, ok);
          __ delayed()->nop();
          __ bind(not_ok);
          __ stop("assert(can be fast path allocated)");
          __ should_not_reach_here();
          __ bind(ok);
          }
#endif // ASSERT
          // if we got here then the TLAB allocation failed, so try
          // refilling the TLAB or allocating directly from eden.
          Label retry_tlab, try_eden;
          __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass

          __ bind(retry_tlab);

          // get the instance size
          __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
          __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
          __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
          __ verify_oop(O0_obj);
          __ mov(O0, I0);
          __ ret();
          __ delayed()->restore();

          __ bind(try_eden);
          // get the instance size
          __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size);
          __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
          __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2);
          __ verify_oop(O0_obj);
          __ mov(O0, I0);
          __ ret();
          __ delayed()->restore();

          __ bind(slow_path);

          // pop this frame so generate_stub_call can push it's own
          __ restore();
        }

        oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_instance), G5_klass);
        // I0->O0: new instance
      }

      break;

#ifdef TIERED
    case counter_overflow_id:
        // G4 contains bci
      oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, counter_overflow), G4);
      break;
#endif // TIERED

    case new_type_array_id:
    case new_object_array_id:
      {
        Register G5_klass = G5; // Incoming
        Register G4_length = G4; // Incoming
        Register O0_obj   = O0; // Outgoing

        Address klass_lh(G5_klass, ((klassOopDesc::header_size() * HeapWordSize)
                                    + Klass::layout_helper_offset_in_bytes()));
        assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
        assert(Klass::_lh_header_size_mask == 0xFF, "bytewise");
        // Use this offset to pick out an individual byte of the layout_helper:
        const int klass_lh_header_size_offset = ((BytesPerInt - 1)  // 3 - 2 selects byte {0,1,0,0}
                                                 - Klass::_lh_header_size_shift / BitsPerByte);

        if (id == new_type_array_id) {
          __ set_info("new_type_array", dont_gc_arguments);
        } else {
          __ set_info("new_object_array", dont_gc_arguments);
        }

#ifdef ASSERT
        // assert object type is really an array of the proper kind
        {
          Label ok;
          Register G3_t1 = G3;
          __ ld(klass_lh, G3_t1);
          __ sra(G3_t1, Klass::_lh_array_tag_shift, G3_t1);
          int tag = ((id == new_type_array_id)
                     ? Klass::_lh_array_tag_type_value
                     : Klass::_lh_array_tag_obj_value);
          __ cmp(G3_t1, tag);
          __ brx(Assembler::equal, false, Assembler::pt, ok);
          __ delayed()->nop();
          __ stop("assert(is an array klass)");
          __ should_not_reach_here();
          __ bind(ok);
        }
#endif // ASSERT

        if (UseTLAB && FastTLABRefill) {
          Label slow_path;
          Register G1_arr_size = G1;
          Register G3_t1 = G3;
          Register O1_t2 = O1;
          assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);

          // check that array length is small enough for fast path
          __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
          __ cmp(G4_length, G3_t1);
          __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
          __ delayed()->nop();

          // if we got here then the TLAB allocation failed, so try
          // refilling the TLAB or allocating directly from eden.
          Label retry_tlab, try_eden;
          __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass

          __ bind(retry_tlab);

          // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
          __ ld(klass_lh, G3_t1);
          __ sll(G4_length, G3_t1, G1_arr_size);
          __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
          __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
          __ add(G1_arr_size, G3_t1, G1_arr_size);
          __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);  // align up
          __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);

          __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path);  // preserves G1_arr_size

          __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
          __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
          __ sub(G1_arr_size, G3_t1, O1_t2);  // body length
          __ add(O0_obj, G3_t1, G3_t1);       // body start
          __ initialize_body(G3_t1, O1_t2);
          __ verify_oop(O0_obj);
          __ retl();
          __ delayed()->nop();

          __ bind(try_eden);
          // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
          __ ld(klass_lh, G3_t1);
          __ sll(G4_length, G3_t1, G1_arr_size);
          __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
          __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
          __ add(G1_arr_size, G3_t1, G1_arr_size);
          __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
          __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);

          __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path);  // preserves G1_arr_size

          __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
          __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
          __ sub(G1_arr_size, G3_t1, O1_t2);  // body length
          __ add(O0_obj, G3_t1, G3_t1);       // body start
          __ initialize_body(G3_t1, O1_t2);
          __ verify_oop(O0_obj);
          __ retl();
          __ delayed()->nop();

          __ bind(slow_path);
        }

        if (id == new_type_array_id) {
          oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
        } else {
          oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_object_array), G5_klass, G4_length);
        }
        // I0 -> O0: new array
      }
      break;

    case new_multi_array_id:
      { // O0: klass
        // O1: rank
        // O2: address of 1st dimension
        __ set_info("new_multi_array", dont_gc_arguments);
        oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_multi_array), I0, I1, I2);
        // I0 -> O0: new multi array
      }
      break;

    case register_finalizer_id:
      {
        __ set_info("register_finalizer", dont_gc_arguments);

        // load the klass and check the has finalizer flag
        Label register_finalizer;
        Register t = O1;
        __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), t);
        __ ld(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), t);
        __ set(JVM_ACC_HAS_FINALIZER, G3);
        __ andcc(G3, t, G0);
        __ br(Assembler::notZero, false, Assembler::pt, register_finalizer);
        __ delayed()->nop();

        // do a leaf return
        __ retl();
        __ delayed()->nop();

        __ bind(register_finalizer);
        OopMap* oop_map = save_live_registers(sasm);
        int call_offset = __ call_RT(noreg, noreg,
                                     CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), I0);
        oop_maps = new OopMapSet();
        oop_maps->add_gc_map(call_offset, oop_map);

        // Now restore all the live registers
        restore_live_registers(sasm);

        __ ret();
        __ delayed()->restore();
      }
      break;

    case throw_range_check_failed_id:
      { __ set_info("range_check_failed", dont_gc_arguments); // arguments will be discarded
        // G4: index
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true);
      }
      break;

    case throw_index_exception_id:
      { __ set_info("index_range_check_failed", dont_gc_arguments); // arguments will be discarded
        // G4: index
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
      }
      break;

    case throw_div0_exception_id:
      { __ set_info("throw_div0_exception", dont_gc_arguments);
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
      }
      break;

    case throw_null_pointer_exception_id:
      { __ set_info("throw_null_pointer_exception", dont_gc_arguments);
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
      }
      break;

    case handle_exception_id:
      {
        __ set_info("handle_exception", dont_gc_arguments);
        // make a frame and preserve the caller's caller-save registers

        oop_maps = new OopMapSet();
        OopMap* oop_map = save_live_registers(sasm);
        __ mov(Oexception->after_save(),  Oexception);
        __ mov(Oissuing_pc->after_save(), Oissuing_pc);
        generate_handle_exception(sasm, oop_maps, oop_map);
      }
      break;

    case unwind_exception_id:
      {
        // O0: exception
        // I7: address of call to this method

        __ set_info("unwind_exception", dont_gc_arguments);
        __ mov(Oexception, Oexception->after_save());
        __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());

        __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
                        Oissuing_pc->after_save());
        __ verify_not_null_oop(Oexception->after_save());
        __ jmp(O0, 0);
        __ delayed()->restore();
      }
      break;

    case throw_array_store_exception_id:
      {
        __ set_info("throw_array_store_exception", dont_gc_arguments);
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), false);
      }
      break;

    case throw_class_cast_exception_id:
      {
        // G4: object
        __ set_info("throw_class_cast_exception", dont_gc_arguments);
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
      }
      break;

    case throw_incompatible_class_change_error_id:
      {
        __ set_info("throw_incompatible_class_cast_exception", dont_gc_arguments);
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
      }
      break;

    case slow_subtype_check_id:
      { // Support for uint StubRoutine::partial_subtype_check( Klass sub, Klass super );
        // Arguments :
        //
        //      ret  : G3
        //      sub  : G3, argument, destroyed
        //      super: G1, argument, not changed
        //      raddr: O7, blown by call
        Label miss;

        __ save_frame(0);               // Blow no registers!

        __ check_klass_subtype_slow_path(G3, G1, L0, L1, L2, L4, NULL, &miss);

        __ mov(1, G3);
        __ ret();                       // Result in G5 is 'true'
        __ delayed()->restore();        // free copy or add can go here

        __ bind(miss);
        __ mov(0, G3);
        __ ret();                       // Result in G5 is 'false'
        __ delayed()->restore();        // free copy or add can go here
      }

    case monitorenter_nofpu_id:
    case monitorenter_id:
      { // G4: object
        // G5: lock address
        __ set_info("monitorenter", dont_gc_arguments);

        int save_fpu_registers = (id == monitorenter_id);
        // make a frame and preserve the caller's caller-save registers
        OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);

        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), G4, G5);

        oop_maps = new OopMapSet();
        oop_maps->add_gc_map(call_offset, oop_map);
        restore_live_registers(sasm, save_fpu_registers);

        __ ret();
        __ delayed()->restore();
      }
      break;

    case monitorexit_nofpu_id:
    case monitorexit_id:
      { // G4: lock address
        // note: really a leaf routine but must setup last java sp
        //       => use call_RT for now (speed can be improved by
        //       doing last java sp setup manually)
        __ set_info("monitorexit", dont_gc_arguments);

        int save_fpu_registers = (id == monitorexit_id);
        // make a frame and preserve the caller's caller-save registers
        OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);

        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), G4);

        oop_maps = new OopMapSet();
        oop_maps->add_gc_map(call_offset, oop_map);
        restore_live_registers(sasm, save_fpu_registers);

        __ ret();
        __ delayed()->restore();

      }
      break;

    case access_field_patching_id:
      { __ set_info("access_field_patching", dont_gc_arguments);
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching));
      }
      break;

    case load_klass_patching_id:
      { __ set_info("load_klass_patching", dont_gc_arguments);
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching));
      }
      break;

    case jvmti_exception_throw_id:
      { // Oexception : exception
        __ set_info("jvmti_exception_throw", dont_gc_arguments);
        oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), I0);
      }
      break;

    case dtrace_object_alloc_id:
      { // O0: object
        __ set_info("dtrace_object_alloc", dont_gc_arguments);
        // we can't gc here so skip the oopmap but make sure that all
        // the live registers get saved.
        save_live_registers(sasm);

        __ save_thread(L7_thread_cache);
        __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc),
                relocInfo::runtime_call_type);
        __ delayed()->mov(I0, O0);
        __ restore_thread(L7_thread_cache);

        restore_live_registers(sasm);
        __ ret();
        __ delayed()->restore();
      }
      break;

#ifndef SERIALGC
    case g1_pre_barrier_slow_id:
      { // G4: previous value of memory
        BarrierSet* bs = Universe::heap()->barrier_set();
        if (bs->kind() != BarrierSet::G1SATBCTLogging) {
          __ save_frame(0);
          __ set((int)id, O1);
          __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
          __ should_not_reach_here();
          break;
        }

        __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments);

        Register pre_val = G4;
        Register tmp  = G1_scratch;
        Register tmp2 = G3_scratch;

        Label refill, restart;
        bool with_frame = false; // I don't know if we can do with-frame.
        int satb_q_index_byte_offset =
          in_bytes(JavaThread::satb_mark_queue_offset() +
                   PtrQueue::byte_offset_of_index());
        int satb_q_buf_byte_offset =
          in_bytes(JavaThread::satb_mark_queue_offset() +
                   PtrQueue::byte_offset_of_buf());
        __ bind(restart);
        __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);

        __ br_on_reg_cond(Assembler::rc_z, /*annul*/false,
                          Assembler::pn, tmp, refill);

        // If the branch is taken, no harm in executing this in the delay slot.
        __ delayed()->ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
        __ sub(tmp, oopSize, tmp);

        __ st_ptr(pre_val, tmp2, tmp);  // [_buf + index] := <address_of_card>
        // Use return-from-leaf
        __ retl();
        __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset);

        __ bind(refill);
        __ save_frame(0);

        __ mov(pre_val, L0);
        __ mov(tmp,     L1);
        __ mov(tmp2,    L2);

        __ call_VM_leaf(L7_thread_cache,
                        CAST_FROM_FN_PTR(address,
                                         SATBMarkQueueSet::handle_zero_index_for_thread),
                                         G2_thread);

        __ mov(L0, pre_val);
        __ mov(L1, tmp);
        __ mov(L2, tmp2);

        __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
        __ delayed()->restore();
      }
      break;

    case g1_post_barrier_slow_id:
      {
        BarrierSet* bs = Universe::heap()->barrier_set();
        if (bs->kind() != BarrierSet::G1SATBCTLogging) {
          __ save_frame(0);
          __ set((int)id, O1);
          __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
          __ should_not_reach_here();
          break;
        }

        __ set_info("g1_post_barrier_slow_id", dont_gc_arguments);

        Register addr = G4;
        Register cardtable = G5;
        Register tmp  = G1_scratch;
        Register tmp2 = G3_scratch;
        jbyte* byte_map_base = ((CardTableModRefBS*)bs)->byte_map_base;

        Label not_already_dirty, restart, refill;

#ifdef _LP64
        __ srlx(addr, CardTableModRefBS::card_shift, addr);
#else
        __ srl(addr, CardTableModRefBS::card_shift, addr);
#endif

        AddressLiteral rs(byte_map_base);
        __ set(rs, cardtable);         // cardtable := <card table base>
        __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]

        __ br_on_reg_cond(Assembler::rc_nz, /*annul*/false, Assembler::pt,
                          tmp, not_already_dirty);
        // Get cardtable + tmp into a reg by itself -- useful in the take-the-branch
        // case, harmless if not.
        __ delayed()->add(addr, cardtable, tmp2);

        // We didn't take the branch, so we're already dirty: return.
        // Use return-from-leaf
        __ retl();
        __ delayed()->nop();

        // Not dirty.
        __ bind(not_already_dirty);
        // First, dirty it.
        __ stb(G0, tmp2, 0);  // [cardPtr] := 0  (i.e., dirty).

        Register tmp3 = cardtable;
        Register tmp4 = tmp;

        // these registers are now dead
        addr = cardtable = tmp = noreg;

        int dirty_card_q_index_byte_offset =
          in_bytes(JavaThread::dirty_card_queue_offset() +
                   PtrQueue::byte_offset_of_index());
        int dirty_card_q_buf_byte_offset =
          in_bytes(JavaThread::dirty_card_queue_offset() +
                   PtrQueue::byte_offset_of_buf());
        __ bind(restart);
        __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);

        __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pn,
                          tmp3, refill);
        // If the branch is taken, no harm in executing this in the delay slot.
        __ delayed()->ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
        __ sub(tmp3, oopSize, tmp3);

        __ st_ptr(tmp2, tmp4, tmp3);  // [_buf + index] := <address_of_card>
        // Use return-from-leaf
        __ retl();
        __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset);

        __ bind(refill);
        __ save_frame(0);

        __ mov(tmp2, L0);
        __ mov(tmp3, L1);
        __ mov(tmp4, L2);

        __ call_VM_leaf(L7_thread_cache,
                        CAST_FROM_FN_PTR(address,
                                         DirtyCardQueueSet::handle_zero_index_for_thread),
                                         G2_thread);

        __ mov(L0, tmp2);
        __ mov(L1, tmp3);
        __ mov(L2, tmp4);

        __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
        __ delayed()->restore();
      }
      break;
#endif // !SERIALGC

    default:
      { __ set_info("unimplemented entry", dont_gc_arguments);
        __ save_frame(0);
        __ set((int)id, O1);
        __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), O1);
        __ should_not_reach_here();
      }
      break;
  }
  return oop_maps;
}
		void phys2d_system_drawer::draw_system(Wt::WPainter& painter, options_t const& options)
		{
			size_t const Margin = 0;

			Wt::WPaintDevice* device = painter.device();

			Wt::WLength dev_width = device->width();
			Wt::WLength dev_height = device->height();
			size_t avail_size = (size_t)std::min(dev_width.toPixels() - 2 * Margin, dev_height.toPixels() - 2 * Margin);

			painter.save();

			Wt::WPen pen(Wt::GlobalColor::lightGray);
			painter.setPen(pen);

			double const scale = (avail_size / 25.0) * options.zoom;

			size_t const GridDim = 5;
			double const GridSquareSize = avail_size / GridDim;

			// TODO: Hack - locking onto first agent
//			auto agent_ptr = dynamic_cast<object const*>(m_sys.m_agents.front().agent.get());
			b2Vec2 grid_ref_pos = b2Vec2(0, 0);//agent_ptr->get_position();

			double x_off = std::fmod(-grid_ref_pos.x * scale, GridSquareSize);
			if(x_off < 0.0)
			{
				x_off += GridSquareSize;
			}
			double y_off = std::fmod(-grid_ref_pos.y * -scale, GridSquareSize);
			if(y_off < 0.0)
			{
				y_off += GridSquareSize;
			}

			for(size_t i = 0; i < dev_width.toPixels() / GridSquareSize; ++i)
			{
				painter.drawLine(
					x_off + i * GridSquareSize,
					0.0,
					x_off + i * GridSquareSize,
					dev_height.toPixels()
					);
			}

			for(size_t i = 0; i < dev_height.toPixels() / GridSquareSize; ++i)
			{
				painter.drawLine(
					0.0,
					y_off + i * GridSquareSize,
					dev_width.toPixels(),
					y_off + i * GridSquareSize
					);
			}

			painter.translate(dev_width.toPixels() / 2, dev_height.toPixels() / 2);
			painter.scale(scale, -scale);
			painter.translate(-grid_ref_pos.x, -grid_ref_pos.y);

			pen = Wt::WPen(Wt::GlobalColor::black);
			painter.setPen(pen);
			Wt::WBrush br(Wt::GlobalColor::white);
			painter.setBrush(br);

			painter.save();

			auto world = m_sys.get_world();
			auto body = world->GetBodyList();
			while(body)
			{
				draw_body(body, painter);

				body = body->GetNext();
			}

			/* TODO: maybe use visitor pattern for entity specific drawing
			http://programmers.stackexchange.com/questions/185525/design-pattern-for-polymorphic-behaviour-while-allowing-library-separation

			m_sys.m_scenario->draw_fixed_objects(painter);

			//phys_system::const_agent_range agents = m_sys.get_agent_range();
			//for(auto it = agents.first; it != agents.second; ++it)
			for(auto const& agent : m_sys.m_agents)
			{
				//(*it)->draw(painter);
				agent.agent->draw(painter);
			}
*/
			painter.restore();
			painter.restore();

			Wt::WFont font = painter.font();
			//font.setFamily(Wt::WFont::Default);
			font.setSize(20);
			painter.setFont(font);
			pen.setColor(Wt::GlobalColor::blue);
			painter.setPen(pen);
			auto rc = Wt::WRectF(
				0,
				0,
				dev_width.toPixels(),
				30
				);
			std::stringstream text;
			text.precision(2);
			std::fixed(text);
			text << m_sys.get_time() << "s";
			painter.drawText(rc, Wt::AlignLeft | Wt::AlignMiddle, text.str());
		}
void CChineseChessView::OnInitialUpdate()
{
	CView::OnInitialUpdate();
	
	// TODO: ÔÚ´ËÌí¼ÓרÓôúÂëºÍ/»òµ÷ÓûùÀà
	NewGame(false);

	CClientDC dc(this);
	CRect rect;
	GetClientRect(&rect);

	bmpBack.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
	bmpBoard.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
	pDCBack->CreateCompatibleDC(&dc);
	pDCBoard->CreateCompatibleDC(&dc);
	pDCBack->SelectObject(&bmpBack);
	pDCBoard->SelectObject(&bmpBoard);

	CBrush br(GetSysColor(COLOR_3DFACE));	
	pDCBoard->FillRect(rect,&br);
	
	CPen pen[2];
	pen[0].CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT));
	pen[1].CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW));
	
	//CPen pen;
	//pen.CreatePen(PS_SOLID,2,RGB(0,0,0));	
	//draw board grid
	//draw chess board	
	for (int i=0;i<2;i++){
		pDCBoard->SelectObject(pen+i);
		for (int i=0;i<10;i++){
			pDCBoard->MoveTo(org.x,org.y+i*lattice_len);
			pDCBoard->LineTo(org.x+8*lattice_len,org.y+i*lattice_len);
		}
		pDCBoard->MoveTo(org);
		pDCBoard->LineTo(org.x,org.y+9*lattice_len);
		pDCBoard->MoveTo(org.x+8*lattice_len,org.y);
		pDCBoard->LineTo(org.x+8*lattice_len,org.y+9*lattice_len);
		for (int i=1;i<=7;i++){
			pDCBoard->MoveTo(org.x+i*lattice_len,org.y);
			pDCBoard->LineTo(org.x+i*lattice_len,org.y+4*lattice_len);
			pDCBoard->MoveTo(org.x+i*lattice_len,org.y+5*lattice_len);
			pDCBoard->LineTo(org.x+i*lattice_len,org.y+9*lattice_len);
		}
		//cross line
		pDCBoard->MoveTo(org.x+3*lattice_len,org.y);
		pDCBoard->LineTo(org.x+5*lattice_len,org.y+2*lattice_len);
		pDCBoard->MoveTo(org.x+5*lattice_len,org.y);
		pDCBoard->LineTo(org.x+3*lattice_len,org.y+2*lattice_len);
		pDCBoard->MoveTo(org.x+3*lattice_len,org.y+7*lattice_len);
		pDCBoard->LineTo(org.x+5*lattice_len,org.y+9*lattice_len);
		pDCBoard->MoveTo(org.x+5*lattice_len,org.y+7*lattice_len);
		pDCBoard->LineTo(org.x+3*lattice_len,org.y+9*lattice_len);
		//add a surrounding boarder
		static int boarder_interval=3;
		pDCBoard->MoveTo(org.x-boarder_interval,org.y-boarder_interval);
		pDCBoard->LineTo(org.x+8*lattice_len+boarder_interval,org.y-boarder_interval);
		pDCBoard->LineTo(org.x+8*lattice_len+boarder_interval,org.y+9*lattice_len+boarder_interval);
		pDCBoard->LineTo(org.x-boarder_interval,org.y+9*lattice_len+boarder_interval);
		pDCBoard->LineTo(org.x-boarder_interval,org.y-boarder_interval);
	}
		

}
Exemple #11
0
 int
fg_write_ASL(ASL *a, const char *stub, NewVCO *nu, int flags)
{
	ASL_fg *asl = (ASL_fg*)a;
	FILE *nl;
	Pf *pf;
	Staticfgw S;
	SufDesc *sd, *sd0;
	cexp *ce, *cee;
	char buf[256], *nbuf, *ts;
	const char *eol, *name, *obase, *s;
	efunc *rops[N_OPS];
	expr_v *v;
	func_info *fi;
	int ak, c, i, j, *ip, *ipe, n, nnc, nne, nno, nnr, nnv, nnzc, nnzo;
	int nx, oblen, rflag;
	linpart *L, *Le;
	real *r, *re, t;
	static NewVCO nu0;

	ASL_CHECK(a, ASL_read_fg, "fg_write");
	if ((comc1 && !c_cexp1st) || (como1 && !o_cexp1st))
		return ASL_writeerr_badcexp1st;
	nnc = nne = nno = nnr = nnv = nnzc = nnzo = 0;
	if (!nu || (nu->nnv == 0 && nu->nnc == 0 && nu->nno == 0))
		nu = &nu0;
	else {
		nnc = nu->nnc;
		nno = nu->nno;
		nnv = nu->nnv;
		if ((nnv <= 0
		  || nnc < 0
		  || nno < 0
		  || nnc + nno <= 0
		  || nnc > 0) && !nu->LUnc)
			return ASL_writeerr_badNewVCO;
		if (LUcheck(nnv, nu->LUnv, nu->Unv, 0, 0))
			return ASL_writeerr_badNewVCO;
		n = n_var + nnv;
		if (nnc) {
			if (LUcheck(nnc, nu->LUnc, nu->Unc, &nnr, &nne))
				return ASL_writeerr_badNewVCO;
			if (ogcheck(n, nnc, nu->newc, &nnzc))
				return ASL_writeerr_badNewVCO;
			}
		if (nno) {
			if (ogcheck(n, nno, nu->newo, &nnzo))
				return ASL_writeerr_badNewVCO;
			if ((s = nu->ot))
			    for(i = 0; i < nno; i++)
				if (s[i] & ~1)
					return ASL_writeerr_badNewVCO;
			if ((r = nu->oc))
			    for(re = r + nno; r < re; r++) {
				if ((t = *r) <= negInfinity
				 || t >= Infinity
				 || t != t)
					return ASL_writeerr_badNewVCO;
				}
			}
		}

	S.r_ops_ = rops;
	for(i = 0; i < N_OPS; i++)
		rops[i] = (efunc*)(unsigned long)i;

	s = name = obase = stub;
	while(*s)
	  switch(*s++) {
		case '/':
		case '\\':
			obase = s;
		}
	c = s - stub;
	nbuf = 0;
	oblen = s - obase;
	if (c <= 3 || strcmp(s - 3, ".nl")) {
		ts = buf;
		if (c + 4 > sizeof(buf))
			ts = nbuf = (char*)Malloc(c+4);
		memcpy(ts, stub, c);
		strcpy(ts+c, ".nl");
		name = ts;
		}
	else
		oblen -= 3;
	nl = fopen(name, "wb");
	if (nbuf)
		free(nbuf);
	if (!nl)
		return ASL_writeerr_openfail;
	i = setjmp(S.wjb);
	if (i) {
		fclose(nl);
		return ASL_writeerr_badrops;
		}
	if (flags & ASL_write_ASCII) {
		ak = 0;
		c = 'g';
		pf = aprintf;
		}
	else {
		ak = Arith_Kind_ASL;
		c = 'b';
		pf = bprintf;
		}
	S.nl_ = nl;
	S.pf_ = pf;
	eol = (char*)(flags & ASL_write_CR ? "\r\n" : "\n");
	fprintf(nl, "%c%d", c, n = ampl_options[0]);
	for(i = 1; i <= n; i++)
		fprintf(nl, " %d", ampl_options[i]);
	if (ampl_options[2] == 3)
		fprintf(nl, " %.g", ampl_vbtol);
	fprintf(nl, "\t# problem %.*s%s", oblen, obase, eol);
	fprintf(nl, " %d %d %d %d", n_var + nnv, n_con + nnc,
		n_obj + nno, nranges + nnr);
	s = "";
	if ((n = n_eqn + nne) >= 0) {
		fprintf(nl, " %d", n);
		s = ", eqns";
		}
	fprintf(nl, "\t# vars, constraints, objectives, ranges%s%s", s, eol);
	if (n_cc | nlcc)
		fprintf(nl, " %d %d %d %d%s%s", nlc, nlo, n_cc, nlcc,
		"\t# nonlinear constrs, objs; ccons: lin, nonlin", eol);
	else
		fprintf(nl, " %d %d\t# nonlinear constraints, objectives%s",
			nlc, nlo, eol);
	fprintf(nl, " %d %d\t# network constraints: nonlinear, linear%s",
		nlnc, lnc, eol);
	fprintf(nl, " %d %d %d%s%s", nlvc, nlvo, nlvb,
		"\t# nonlinear vars in constraints, objectives, both", eol);
	s = "";
	fprintf(nl, " %d %d", nwv, nfunc);
	if (ak | asl->i.flags) {
		fprintf(nl, " %d %d", ak, asl->i.flags);
		s = "; arith, flags";
		}
	fprintf(nl, "\t# linear network variables; functions%s%s", s, eol);
	fprintf(nl, " %d %d %d %d %d%s%s", nbv, niv, nlvbi, nlvci, nlvoi,
		"\t# discrete variables: binary, integer, nonlinear (b,c,o)",
		eol);
	fprintf(nl, " %d %d\t# nonzeros in Jacobian, gradients%s",
		nzc + nnzc, nzo + nnzo, eol);
	fprintf(nl, " 0 0\t# max name lengths: constraints, variables%s", eol);
	fprintf(nl, " %d %d %d %d %d\t# common exprs: b,c,o,c1,o1%s",
		comb, comc, como, comc1, como1, eol);

	for(i = 0; i < nfunc; i++) {
		fi = funcs[i];
		fi->findex = i; /* for eput */
		(*pf)(nl, "F%d %d %d %s\n", i, fi->ftype, fi->nargs, fi->name);
		}

	for(i = 0; i < 4; i++) {
		if (!(sd = asl->i.suffixes[i]))
			continue;
		nx = (&asl->i.n_var_)[i];
		for(sd = sd0 = reverse(sd); sd; sd = sd->next) {
			n = rflag = 0;
			if (sd->kind & ASL_Sufkind_real) {
				rflag = ASL_Sufkind_real;
				r = sd->u.r;
				re = r + nx;
				while(r < re)
					if (*r++)
						n++;
				}
			else {
				ip = sd->u.i;
				ipe = ip + nx;
				while(ip < ipe)
					if (*ip++)
						n++;
				}
			if (!n)
				continue;
			(*pf)(nl, "S%d %d %s\n", i | rflag, n, sd->sufname);
			j = 0;
			if (rflag) {
				r = sd->u.r;
				for(; j < nx; j++)
					if (r[j])
						(*pf)(nl, "%d %g\n", j, r[j]);
				}
			else {
				ip = sd->u.i;
				for(; j < nx; j++)
					if (ip[j])
						(*pf)(nl, "%d %d\n", j, ip[j]);
				}
			}
		reverse(sd0);
		}
	ce = cexps;
	n = n_var + nnv;
	S.v = var_e;
	for(cee = ce + comb + comc + como; ce < cee; ce++) {
		(*pf)(nl, "V%d %d %d\n", n++, ce->nlin, 0);
		L = ce->L;
		for(Le = L + ce->nlin; L < Le; L++) {
			v = (expr_v*)((char*)L->v.rp - offset_of(expr_v,v));
			(*pf)(nl, "%d %g\n", (int)(v - S.v), L->fac);
			}
		eput(&S, ce->e);
		}
	S.cexps1_ = asl->I.cexps1_;
	S.nv0 = n_var;
	S.com1off = S.nv0 + comb + comc + como;
	coput(&S, 'C', con_de, n_con, c_cexp1st, 0, 0, nnc, 0, 0);
	coput(&S, 'O', obj_de, n_obj, o_cexp1st, objtype, n_con,
		nno, nu->oc, nu->ot);
	iguess(pf, nl, 'd', pi0, havepi0, n_con, nnc, nu->d0);
	iguess(pf, nl, 'x', X0, havex0, n_var, nnv, nu->x0);
	br(pf, nl, 'r', LUrhs, Urhsx, n_con);
	br(pf, nl, 0, nu->LUnc, nu->Unc, nnc);
	br(pf, nl, 'b', LUv, Uvx, n_var);
	br(pf, nl, 0, nu->LUnv, nu->Unv, nnv);
	if (A_vals)
		k1put(pf, nl, A_colstarts, A_vals, A_rownos, n_con, n_var,
			nnv, nnc, nu->newc);
	else
		k2put(pf, nl, Cgrad, n_con, n_var, 1, nnv, nnc, nu->newc);

	Gput(pf, nl, 'G', 0, n_obj, Ograd);
	Gput(pf, nl, 'G', n_obj, nno, nu->newo);

	fclose(nl);
	return 0;
	}
Exemple #12
0
    // Paints the tabs that intersect the window's update rectangle.
    void Paint(HDC hdc, RECT &rc) {
        IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);

        // paint the background
        bool isTranslucentMode = inTitlebar && dwm::IsCompositionEnabled();
        if (isTranslucentMode)
            PaintParentBackground(hwnd, hdc);
        else {
            HBRUSH brush = CreateSolidBrush(color.bar);
            FillRect(hdc, &rc, brush);
            DeleteObject(brush);
        }

        // TODO: GDI+ doesn't seem to cope well with SetWorldTransform
        XFORM ctm = { 1.0, 0, 0, 1.0, 0, 0 };
        SetWorldTransform(hdc, &ctm);

        Graphics graphics(hdc);
        graphics.SetCompositingMode(CompositingModeSourceCopy);
        graphics.SetCompositingQuality(CompositingQualityHighQuality);
        graphics.SetSmoothingMode(SmoothingModeHighQuality);
        graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
        graphics.SetPageUnit(UnitPixel);
        GraphicsPath shapes(data->Points, data->Types, data->Count);
        GraphicsPath shape;
        GraphicsPathIterator iterator(&shapes);

        SolidBrush br(Color(0, 0, 0));
        Pen pen(&br);

        Font f(hdc, GetDefaultGuiFont());
        // TODO: adjust these constant values for DPI?
        RectF layout(3.0f, 1.0f, REAL(width - 20), (REAL)height);
        StringFormat sf(StringFormat::GenericDefault());
        sf.SetFormatFlags(StringFormatFlagsNoWrap);
        sf.SetLineAlignment(StringAlignmentCenter);
        sf.SetTrimming(StringTrimmingEllipsisCharacter);

        REAL yPosTab = inTitlebar ? 0.0f : REAL(ClientRect(hwnd).dy - height - 1);
        for (int i = 0; i < Count(); i++) {
            graphics.ResetTransform();
            graphics.TranslateTransform(1.f + (REAL)(width + 1) * i - (REAL)rc.left, yPosTab - (REAL)rc.top);

            if (!graphics.IsVisible(0, 0, width + 1, height + 1))
                continue;

            // in firefox style we only paint current and highlighed tabs
            // all other tabs only show 
            bool onlyText = g_FirefoxStyle && !((current == i) || (highlighted == i));
            if (onlyText) {
#if 0
                // we need to first paint the background with the same color as caption,
                // otherwise the text looks funny (because is transparent?)
                // TODO: what is the damn bg color of caption? bar is too light, outline is too dark
                Color bgColTmp;
                bgColTmp.SetFromCOLORREF(color.bar);
                {
                    SolidBrush bgBr(bgColTmp);
                    graphics.FillRectangle(&bgBr, layout);
                }
                bgColTmp.SetFromCOLORREF(color.outline);
                {
                    SolidBrush bgBr(bgColTmp);
                    graphics.FillRectangle(&bgBr, layout);
                }
#endif
                // TODO: this is a hack. If use use no background and cleartype, the
                // text looks funny (is bold).
                // CompositingModeSourceCopy doesn't work with clear type
                // another option is to draw background before drawing text, but
                // I can't figure out what is the actual color of caption
                graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
                graphics.SetCompositingMode(CompositingModeSourceCopy);
                //graphics.SetCompositingMode(CompositingModeSourceOver);
                graphics.DrawString(text.At(i), -1, &f, layout, &sf, LoadBrush(br, color.text));
                graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
                continue;
            }


            COLORREF bgCol = color.background;;
            if (current == i) {
                bgCol = color.current;
            } else if (highlighted == i) {
                bgCol = color.highlight;
            }

            // paint tab's body
            graphics.SetCompositingMode(CompositingModeSourceCopy);
            iterator.NextMarker(&shape);
            LoadBrush(br, bgCol);
            graphics.FillPath(&br, &shape);

            // draw tab's text
            graphics.SetCompositingMode(CompositingModeSourceOver);
            graphics.DrawString(text.At(i), -1, &f, layout, &sf, LoadBrush(br, color.text));

            // paint "x"'s circle
            iterator.NextMarker(&shape);
            if (xClicked == i)
                graphics.FillPath(LoadBrush(br, color.x_click), &shape);
            else if (xHighlighted == i)
                graphics.FillPath(LoadBrush(br, color.x_highlight), &shape);

            // paint "x"
            iterator.NextMarker(&shape);
            if (xClicked == i || xHighlighted == i)
                LoadPen(pen, color.x_line, 2.0f);
            else
                LoadPen(pen, color.outline, 2.0f);
            graphics.DrawPath(&pen, &shape);
            iterator.Rewind();
        }
    }
Exemple #13
0
bool
Warp::accelerated_cairorender(Context context, cairo_t *cr, int quality, const RendDesc &renddesc_, ProgressCallback *cb)const
{
	Point src_tl=param_src_tl.get(Point());
	Point src_br=param_src_br.get(Point());
	Point dest_tl=param_dest_tl.get(Point());
	Point dest_tr=param_dest_tr.get(Point());
	Point dest_bl=param_dest_bl.get(Point());
	Point dest_br=param_dest_br.get(Point());
	Real horizon=param_horizon.get(Real());
	bool clip=param_clip.get(bool());

	SuperCallback stageone(cb,0,9000,10000);
	SuperCallback stagetwo(cb,9000,10000,10000);
	
	
	RendDesc renddesc(renddesc_);
	// Untransform the render desc
	if(!cairo_renddesc_untransform(cr, renddesc))
		return false;
	
	Real pw=(renddesc.get_w())/(renddesc.get_br()[0]-renddesc.get_tl()[0]);
	Real ph=(renddesc.get_h())/(renddesc.get_br()[1]-renddesc.get_tl()[1]);
	
	if(cb && !cb->amount_complete(0,10000))
		return false;
	
	Point tl(renddesc.get_tl());
	Point br(renddesc.get_br());
	
	Rect bounding_rect;
	
	Rect render_rect(tl,br);
	Rect clip_rect(Rect::full_plane());
	Rect dest_rect(dest_tl,dest_br); dest_rect.expand(dest_tr).expand(dest_bl);
	
	Real zoom_factor(1.0);
	
	// Quick exclusion clip, if necessary
	if(clip && !intersect(render_rect,dest_rect))
	{
		cairo_save(cr);
		cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
		cairo_paint(cr);
		cairo_restore(cr);
		return true;
	}
	
	{
		Rect other(render_rect);
		if(clip)
			other&=dest_rect;
		
		Point min(other.get_min());
		Point max(other.get_max());
		
		bool init_point_set=false;
		
		// Point trans_point[4];
		Point p;
		// Real trans_z[4];
		Real z,minz(10000000000000.0f),maxz(0);
		
		//! \todo checking the 4 corners for 0<=z<horizon*2 and using
		//! only 4 corners which satisfy this condition isn't the
		//! right thing to do.  It's possible that none of the 4
		//! corners fall within that range, and yet content of the
		//! tile does.
		p=transform_forward(min);
		z=transform_backward_z(p);
		if(z>0 && z<horizon*2)
		{
			if(init_point_set)
				bounding_rect.expand(p);
			else
				bounding_rect=Rect(p);
			init_point_set=true;
			maxz=std::max(maxz,z);
			minz=std::min(minz,z);
		}
		
		p=transform_forward(max);
		z=transform_backward_z(p);
		if(z>0 && z<horizon*2)
		{
			if(init_point_set)
				bounding_rect.expand(p);
			else
				bounding_rect=Rect(p);
			init_point_set=true;
			maxz=std::max(maxz,z);
			minz=std::min(minz,z);
		}
		
		swap(min[1],max[1]);
		
		p=transform_forward(min);
		z=transform_backward_z(p);
		if(z>0 && z<horizon*2)
		{
			if(init_point_set)
				bounding_rect.expand(p);
			else
				bounding_rect=Rect(p);
			init_point_set=true;
			maxz=std::max(maxz,z);
			minz=std::min(minz,z);
		}
		
		p=transform_forward(max);
		z=transform_backward_z(p);
		if(z>0 && z<horizon*2)
		{
			if(init_point_set)
				bounding_rect.expand(p);
			else
				bounding_rect=Rect(p);
			init_point_set=true;
			maxz=std::max(maxz,z);
			minz=std::min(minz,z);
		}
		
		if(!init_point_set)
		{
			cairo_save(cr);
			cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
			cairo_paint(cr);
			cairo_restore(cr);
			return true;
		}
		zoom_factor=(1+(maxz-minz));
		
	}
	
#ifdef ACCEL_WARP_IS_BROKEN
	return Layer::accelerated_cairorender(context,cr,quality,renddesc, cb);
#else
	
	/*swap(tl[1],br[1]);
	 bounding_rect
	 .expand(transform_forward(tl))
	 .expand(transform_forward(br))
	 ;
	 swap(tl[1],br[1]);*/
	
	//synfig::warning("given window: [%f,%f]-[%f,%f] %dx%d",tl[0],tl[1],br[0],br[1],renddesc.get_w(),renddesc.get_h());
	//synfig::warning("Projected: [%f,%f]-[%f,%f]",bounding_rect.get_min()[0],bounding_rect.get_min()[1],bounding_rect.get_max()[0],bounding_rect.get_max()[1]);
	
	// If we are clipping, then go ahead and clip to the
	// source rectangle
	if(clip)
		clip_rect&=Rect(src_tl,src_br);
	
	// Bound ourselves to the bounding rectangle of
	// what is under us
	clip_rect&=context.get_full_bounding_rect();//.expand_x(abs(zoom_factor/pw)).expand_y(abs(zoom_factor/ph));
	
	bounding_rect&=clip_rect;
	
	Point min_point(bounding_rect.get_min());
	Point max_point(bounding_rect.get_max());
	
	// we're going to divide by the difference of these pairs soon;
	// if they're the same, we'll be dividing by zero, and we don't
	// want to do that!
	// \todo what should we do in this case?
	if (min_point[0] == max_point[0]) max_point[0] += 0.001;
	if (min_point[1] == max_point[1]) max_point[1] += 0.001;
	
	if(tl[0]>br[0])
	{
		tl[0]=max_point[0];
		br[0]=min_point[0];
	}
	else
	{
		br[0]=max_point[0];
		tl[0]=min_point[0];
	}
	if(tl[1]>br[1])
	{
		tl[1]=max_point[1];
		br[1]=min_point[1];
	}
	else
	{
		br[1]=max_point[1];
		tl[1]=min_point[1];
	}
	
	const int tmp_d(max(renddesc.get_w(),renddesc.get_h()));
	Real src_pw=(tmp_d*zoom_factor)/(br[0]-tl[0]);
	Real src_ph=(tmp_d*zoom_factor)/(br[1]-tl[1]);
	
	
	RendDesc desc(renddesc);
	desc.clear_flags();
	//desc.set_flags(RendDesc::PX_ASPECT);
	desc.set_tl(tl);
	desc.set_br(br);
	desc.set_wh(ceil_to_int(src_pw*(br[0]-tl[0])),ceil_to_int(src_ph*(br[1]-tl[1])));
	
	//synfig::warning("surface to render: [%f,%f]-[%f,%f] %dx%d",desc.get_tl()[0],desc.get_tl()[1],desc.get_br()[0],desc.get_br()[1],desc.get_w(),desc.get_h());
	if(desc.get_w()==0 && desc.get_h()==0)
	{
		cairo_save(cr);
		cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
		cairo_paint(cr);
		cairo_restore(cr);
		return true;
	}
	
	// Recalculate the pixel widths for the src renddesc
	src_pw=(desc.get_w())/(desc.get_br()[0]-desc.get_tl()[0]);
	src_ph=(desc.get_h())/(desc.get_br()[1]-desc.get_tl()[1]);
	
	cairo_surface_t* source=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, desc.get_w(),desc.get_h());
	cairo_surface_t* surface=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA,renddesc.get_w(), renddesc.get_h());
	cairo_t* subcr=cairo_create(source);
	cairo_scale(subcr, 1/desc.get_pw(), 1/desc.get_ph());
	cairo_translate(subcr, -desc.get_tl()[0], -desc.get_tl()[1]);

	if(!context.accelerated_cairorender(subcr,quality,desc,&stageone))
		return false;
	
	cairo_destroy(subcr);
		
	int surfacew, surfaceh, sourcew, sourceh;
	
	CairoSurface csurface(surface);
	CairoSurface csource(source);
	
	csurface.map_cairo_image();
	csource.map_cairo_image();
	
	surfacew=csurface.get_w();
	surfaceh=csurface.get_h();
	sourcew=csource.get_w();
	sourceh=csource.get_h();
	
	CairoSurface::pen pen(csurface.begin());
	
	// Do the warp
	{
		int x,y;
		float u,v;
		Point point,tmp;
		for(y=0,point[1]=renddesc.get_tl()[1];y<surfaceh;y++,pen.inc_y(),pen.dec_x(x),point[1]+=1.0/ph)
		{
			for(x=0,point[0]=renddesc.get_tl()[0];x<surfacew;x++,pen.inc_x(),point[0]+=1.0/pw)
			{
				tmp=transform_forward(point);
				const float z(transform_backward_z(tmp));
				if(!clip_rect.is_inside(tmp) || !(z>0 && z<horizon))
				{
					csurface[y][x]=Color::alpha();
					continue;
				}
				
				u=(tmp[0]-tl[0])*src_pw;
				v=(tmp[1]-tl[1])*src_ph;
				
				if(u<0 || v<0 || u>=sourcew || v>=sourceh || isnan(u) || isnan(v))
					csurface[y][x]=context.get_cairocolor(tmp);
				else
				{
					// CUBIC
					if(quality<=4)
						csurface[y][x]=csource.cubic_sample_cooked(u,v);
					// INTEPOLATION_LINEAR
					else if(quality<=6)
						csurface[y][x]=csource.linear_sample_cooked(u,v);
					else
						// NEAREST_NEIGHBOR
						csurface[y][x]=csource[floor_to_int(v)][floor_to_int(u)];
				}
			}
			if((y&31)==0 && cb)
			{
				if(!stagetwo.amount_complete(y,surfaceh))
					return false;
			}
		}
	}
	
#endif
	
	if(cb && !cb->amount_complete(10000,10000)) return false;
	
	csurface.unmap_cairo_image();
	csource.unmap_cairo_image();
	cairo_surface_destroy(source);
	
	cairo_save(cr);
	
	cairo_translate(cr, renddesc.get_tl()[0], renddesc.get_tl()[1]);
	cairo_scale(cr, renddesc.get_pw(), renddesc.get_ph());
	cairo_set_source_surface(cr, surface, 0, 0);
	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
	cairo_paint(cr);
	
	cairo_restore(cr);
	
	cairo_surface_destroy(surface);
	return true;
}
Exemple #14
0
// LP64 passes floating point arguments in F1, F3, F5, etc. instead of
// O0, O1, O2 etc..
// Doubles are passed in D0, D2, D4
// We store the signature of the first 16 arguments in the first argument
// slot because it will be overwritten prior to calling the native
// function, with the pointer to the JNIEnv.
// If LP64 there can be up to 16 floating point arguments in registers
// or 6 integer registers.
address AbstractInterpreterGenerator::generate_slow_signature_handler() {

  enum {
    non_float  = 0,
    float_sig  = 1,
    double_sig = 2,
    sig_mask   = 3
  };

  address entry = __ pc();
  Argument argv(0, true);

  // We are in the jni transition frame. Save the last_java_frame corresponding to the
  // outer interpreter frame
  //
  __ set_last_Java_frame(FP, noreg);
  // make sure the interpreter frame we've pushed has a valid return pc
  __ mov(O7, I7);
  __ mov(Lmethod, G3_scratch);
  __ mov(Llocals, G4_scratch);
  __ save_frame(0);
  __ mov(G2_thread, L7_thread_cache);
  __ add(argv.address_in_frame(), O3);
  __ mov(G2_thread, O0);
  __ mov(G3_scratch, O1);
  __ call(CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), relocInfo::runtime_call_type);
  __ delayed()->mov(G4_scratch, O2);
  __ mov(L7_thread_cache, G2_thread);
  __ reset_last_Java_frame();


  // load the register arguments (the C code packed them as varargs)
  Address Sig = argv.address_in_frame();        // Argument 0 holds the signature
  __ ld_ptr( Sig, G3_scratch );                   // Get register argument signature word into G3_scratch
  __ mov( G3_scratch, G4_scratch);
  __ srl( G4_scratch, 2, G4_scratch);             // Skip Arg 0
  Label done;
  for (Argument ldarg = argv.successor(); ldarg.is_float_register(); ldarg = ldarg.successor()) {
    Label NonFloatArg;
    Label LoadFloatArg;
    Label LoadDoubleArg;
    Label NextArg;
    Address a = ldarg.address_in_frame();
    __ andcc(G4_scratch, sig_mask, G3_scratch);
    __ br(Assembler::zero, false, Assembler::pt, NonFloatArg);
    __ delayed()->nop();

    __ cmp(G3_scratch, float_sig );
    __ br(Assembler::equal, false, Assembler::pt, LoadFloatArg);
    __ delayed()->nop();

    __ cmp(G3_scratch, double_sig );
    __ br(Assembler::equal, false, Assembler::pt, LoadDoubleArg);
    __ delayed()->nop();

    __ bind(NonFloatArg);
    // There are only 6 integer register arguments!
    if ( ldarg.is_register() )
      __ ld_ptr(ldarg.address_in_frame(), ldarg.as_register());
    else {
    // Optimization, see if there are any more args and get out prior to checking
    // all 16 float registers.  My guess is that this is rare.
    // If is_register is false, then we are done the first six integer args.
      __ tst(G4_scratch);
      __ brx(Assembler::zero, false, Assembler::pt, done);
      __ delayed()->nop();

    }
    __ ba(false, NextArg);
    __ delayed()->srl( G4_scratch, 2, G4_scratch );

    __ bind(LoadFloatArg);
    __ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4);
    __ ba(false, NextArg);
    __ delayed()->srl( G4_scratch, 2, G4_scratch );

    __ bind(LoadDoubleArg);
    __ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() );
    __ ba(false, NextArg);
    __ delayed()->srl( G4_scratch, 2, G4_scratch );

    __ bind(NextArg);

  }

  __ bind(done);
  __ ret();
  __ delayed()->
     restore(O0, 0, Lscratch);  // caller's Lscratch gets the result handler
  return entry;
}
// Used by compiler only; may use only caller saved, non-argument registers
// NOTE:  %%%% if any change is made to this stub make sure that the function
//             pd_code_size_limit is changed to ensure the correct size for VtableStub
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
  const int sparc_code_length = VtableStub::pd_code_size_limit(true);
  VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index);
  ResourceMark rm;
  CodeBuffer cb(s->entry_point(), sparc_code_length);
  MacroAssembler* masm = new MacroAssembler(&cb);

#ifndef PRODUCT
  if (CountCompiledCalls) {
    __ inc_counter(SharedRuntime::nof_megamorphic_calls_addr(), G5, G3_scratch);
  }
#endif /* PRODUCT */

  assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");

  // get receiver klass
  address npe_addr = __ pc();
  __ load_klass(O0, G3_scratch);

  // set methodOop (in case of interpreted method), and destination address
  int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
#ifndef PRODUCT
  if (DebugVtables) {
    Label L;
    // check offset vs vtable length
    __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
    __ cmp(G5, vtable_index*vtableEntry::size());
    __ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
    __ delayed()->nop();
    __ set(vtable_index, O2);
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
    __ bind(L);
  }
#endif
  int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
  if( __ is_simm13(v_off) ) {
    __ ld_ptr(G3, v_off, G5_method);
  } else {
    __ set(v_off,G5);
    __ ld_ptr(G3, G5, G5_method);
  }

#ifndef PRODUCT
  if (DebugVtables) {
    Label L;
    __ br_notnull(G5_method, false, Assembler::pt, L);
    __ delayed()->nop();
    __ stop("Vtable entry is ZERO");
    __ bind(L);
  }
#endif

  address ame_addr = __ pc();  // if the vtable entry is null, the method is abstract
                               // NOTE: for vtable dispatches, the vtable entry will never be null.

  __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3_scratch);

  // jump to target (either compiled code or c2iadapter)
  __ JMP(G3_scratch, 0);
  // load methodOop (in case we call c2iadapter)
  __ delayed()->nop();

  masm->flush();

  if (PrintMiscellaneous && (WizardMode || Verbose)) {
    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
                  vtable_index, s->entry_point(),
                  (int)(s->code_end() - s->entry_point()),
                  (int)(s->code_end() - __ pc()));
  }
  guarantee(__ pc() <= s->code_end(), "overflowed buffer");
  // shut the door on sizing bugs
  int slop = 2*BytesPerInstWord;  // 32-bit offset is this much larger than a 13-bit one
  assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for sethi;add");

  s->set_exception_points(npe_addr, ame_addr);
  return s;
}
Exemple #16
0
void Multiplexer::OnMultiplexerHeader(
    size_t peer, uint32_t seq, Connection& s, net::Buffer&& buffer) {

    die_unless(d_->ongoing_requests_[peer] > 0);
    d_->ongoing_requests_[peer]--;

    // received invalid Buffer: the connection has closed?
    if (!buffer.IsValid()) return;

    net::BufferReader br(buffer);
    StreamMultiplexerHeader header = StreamMultiplexerHeader::Parse(br);

    LOG << "OnMultiplexerHeader() header"
        << " magic=" << unsigned(header.magic)
        << " size=" << header.size
        << " num_items=" << header.num_items
        << " first_item=" << header.first_item
        << " typecode_verify=" << header.typecode_verify
        << " stream_id=" << header.stream_id;

    // received stream id
    StreamId id = header.stream_id;
    size_t local_worker = header.receiver_local_worker;

    // round of allocation size to next power of two
    size_t alloc_size = header.size;
    if (alloc_size < THRILL_DEFAULT_ALIGN) alloc_size = THRILL_DEFAULT_ALIGN;
    alloc_size = tlx::round_up_to_power_of_two(alloc_size);

    if (header.magic == MagicByte::CatStreamBlock)
    {
        CatStreamDataPtr stream = GetOrCreateCatStreamData(
            id, local_worker, /* dia_id (unknown at this time) */ 0);
        stream->rx_net_bytes_ += buffer.size();

        if (header.IsEnd()) {
            sLOG << "end of stream on" << s << "in CatStream" << id
                 << "from worker" << header.sender_worker;

            stream->OnStreamBlock(
                header.sender_worker, header.seq, Block());
        }
        else {
            sLOG << "stream header from" << s << "on CatStream" << id
                 << "from worker" << header.sender_worker
                 << "for local_worker" << local_worker
                 << "seq" << header.seq
                 << "size" << header.size;

            PinnedByteBlockPtr bytes = block_pool_.AllocateByteBlock(
                alloc_size, local_worker);
            sLOG << "new PinnedByteBlockPtr bytes=" << *bytes;

            d_->ongoing_requests_[peer]++;

            dispatcher_.AsyncRead(
                s, seq + 1, header.size, std::move(bytes),
                [this, peer, header, stream](
                    Connection& s, PinnedByteBlockPtr&& bytes) {
                    OnCatStreamBlock(peer, s, header, stream, std::move(bytes));
                });
        }
    }
    else if (header.magic == MagicByte::MixStreamBlock)
    {
        MixStreamDataPtr stream = GetOrCreateMixStreamData(
            id, local_worker, /* dia_id (unknown at this time) */ 0);
        stream->rx_net_bytes_ += buffer.size();

        if (header.IsEnd()) {
            sLOG << "end of stream on" << s << "in MixStream" << id
                 << "from worker" << header.sender_worker;

            stream->OnStreamBlock(header.sender_worker, header.seq, Block());
        }
        else {
            sLOG << "stream header from" << s << "on MixStream" << id
                 << "from worker" << header.sender_worker
                 << "for local_worker" << local_worker
                 << "seq" << header.seq
                 << "size" << header.size;

            PinnedByteBlockPtr bytes = block_pool_.AllocateByteBlock(
                alloc_size, local_worker);

            d_->ongoing_requests_[peer]++;

            dispatcher_.AsyncRead(
                s, seq + 1, header.size, std::move(bytes),
                [this, peer, header, stream](
                    Connection& s, PinnedByteBlockPtr&& bytes) mutable {
                    OnMixStreamBlock(peer, s, header, stream, std::move(bytes));
                });
        }
    }
    else {
        die("Invalid magic byte in MultiplexerHeader");
    }

    AsyncReadMultiplexerHeader(peer, s);
}
inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) {
  insert_nop_after_cbcond();
  br(c, a, p, target(L));
}
Exemple #18
0
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destroyOldWindow*/)
{
    Q_Q(QWidget);
    Qt::WindowType type = q->windowType();
    Qt::WindowFlags flags = data.window_flags;

    data.alloc_region_index = -1;

    // we don't have a "Drawer" window type
    if (type == Qt::Drawer) {
        type = Qt::Widget;
        flags &= ~Qt::WindowType_Mask;
    }


    bool topLevel = (flags & Qt::Window);
    bool popup = (type == Qt::Popup);
    bool dialog = (type == Qt::Dialog
                   || type == Qt::Sheet
                   || (flags & Qt::MSWindowsFixedSizeDialogHint));
    bool desktop = (type == Qt::Desktop);
    bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip);


#ifndef QT_NO_WARNING_OUTPUT
    static bool toolWarningShown = false;
    if (!toolWarningShown && type == Qt::Tool && !(flags & Qt::FramelessWindowHint)) {
        qWarning("Qt for Embedded Linux " QT_VERSION_STR " does not support tool windows with frames.\n"
                 "This behavior will change in a later release. To ensure compatibility with\n"
                 "future versions, use (Qt::Tool | Qt::FramelessWindowHint).");
        toolWarningShown = true;
    }
#endif

    WId           id;
    QWSDisplay* dpy = QWidget::qwsDisplay();

    if (!window)                                // always initialize
        initializeWindow = true;

    // use the size of the primary screen to determine the default window size
    QList<QScreen *> screens = qt_screen->subScreens();
    if (screens.isEmpty())
        screens.append(qt_screen);
    int sw = screens[0]->width();
    int sh = screens[0]->height();

    if (desktop) {                                // desktop widget
        dialog = popup = false;                        // force these flags off
        data.crect.setRect(0, 0, sw, sh);
    } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
        data.crect.setSize(QSize(sw/2, 4*sh/10));
    }

    if (window) {                                // override the old window
        id = window;
        setWinId(window);
    } else if (desktop) {                        // desktop widget
        id = (WId)-2;                                // id = root window
#if 0
        QWidget *otherDesktop = q->find(id);        // is there another desktop?
        if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
            otherDesktop->d_func()->setWinId(0);        // remove id from widget mapper
            setWinId(id);                        // make sure otherDesktop is
            otherDesktop->d_func()->setWinId(id);        //   found first
        } else
#endif
        {
            setWinId(id);
        }
    } else {
        id = topLevel ? dpy->takeId() : takeLocalId();
        setWinId(id);                                // set widget id/handle + hd
    }


    bool hasFrame = true;
    if (topLevel) {
        if (desktop || popup || tool || q->testAttribute(Qt::WA_DontShowOnScreen))
            hasFrame = false;
        else
            hasFrame = !(flags & Qt::FramelessWindowHint);
    }
    if (desktop) {
        q->setAttribute(Qt::WA_WState_Visible);
    } else if (topLevel) {                        // set X cursor
        //QCursor *oc = QApplication::overrideCursor();
        if (initializeWindow) {
            //XXX XDefineCursor(dpy, winid, oc ? oc->handle() : cursor().handle());
        }
        QWidget::qwsDisplay()->nameRegion(q->internalWinId(), q->objectName(), q->windowTitle());
    }

    if (topLevel) {
        createTLExtra();
        QTLWExtra *topextra = extra->topextra;
#ifndef QT_NO_QWS_MANAGER
        if (hasFrame) {
            // get size of wm decoration and make the old crect the new frect
            QRect cr = data.crect;
            QRegion r = QApplication::qwsDecoration().region(q, cr) | cr;
            QRect br(r.boundingRect());
            topextra->frameStrut.setCoords(cr.x() - br.x(),
                                                  cr.y() - br.y(),
                                                  br.right() - cr.right(),
                                                  br.bottom() - cr.bottom());
            if (!q->testAttribute(Qt::WA_Moved) || topextra->posFromMove)
                data.crect.translate(topextra->frameStrut.left(), topextra->frameStrut.top());
            if (!topData()->qwsManager) {
                topData()->qwsManager = new QWSManager(q);
                if(q->data->window_state & ~Qt::WindowActive == Qt::WindowMaximized)
                    topData()->qwsManager->maximize();
            }

        } else if (topData()->qwsManager) {
            delete topData()->qwsManager;
            topData()->qwsManager = 0;
            data.crect.translate(-topextra->frameStrut.left(), -topextra->frameStrut.top());
            topextra->frameStrut.setCoords(0, 0, 0, 0);
        }
#endif
        if (!topextra->caption.isEmpty())
            setWindowTitle_helper(topextra->caption);

        //XXX If we are session managed, inform the window manager about it
    } else {
        if (extra && extra->topextra)        { // already allocated due to reparent?
            extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
        }
        //updateRequestedRegion(mapToGlobal(QPoint(0,0)));
    }
}
void FearGuiScrollCtrl::drawBorder(GFXSurface *sfc, const Point2I &offset)
{
   bool ghosted = disabled;
   if (root)
   {
      SimGui::Control *topDialog = root->getDialogNumber(root->findDialogNumber(this) + 1);
      if (topDialog && (topDialog != getTopMostParent()) && (topDialog->findControlWithTag(IDCTG_DIALOG)))
      {
         ghosted = TRUE;
      }
   }
   
   if (borderThickness > 1)
   {
      if (mbOpaque)
      {
         sfc->drawRect2d_f(&RectI(offset.x, offset.y, offset.x + extent.x - 1, offset.y + extent.y - 1), fillColor);
      }
      
      int colorTable[8] =
      {
      	BOX_INSIDE,
      	BOX_OUTSIDE,
      	BOX_LAST_PIX,
      	GREEN_78,
      	BOX_GHOST_INSIDE,
      	BOX_GHOST_OUTSIDE,
      	BOX_GHOST_LAST_PIX,
      	BOX_GHOST_INSIDE,   
      };
      
      int colorOffset = (ghosted ? 4 : 0);
      Point2I tl = offset;
      Point2I br(offset.x + extent.x - 1, offset.y + extent.y - 1);
      int spc = 4;
      
      //top edge
      sfc->drawLine2d(&Point2I(tl.x + spc, tl.y),
                      &Point2I(br.x - spc, tl.y),
                      colorTable[0 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + spc, tl.y + 1),
                      &Point2I(br.x - spc, tl.y + 1),
                      colorTable[1 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + spc, tl.y + 2),
                      &Point2I(br.x - spc, tl.y + 2),
                      BLACK);
      sfc->drawPoint2d(&Point2I(tl.x + spc - 1, tl.y + 1), colorTable[0 + colorOffset]);
      sfc->drawPoint2d(&Point2I(br.x - spc + 1, tl.y + 1), colorTable[0 + colorOffset]);
      
      //bottom edge
      sfc->drawLine2d(&Point2I(tl.x + spc, br.y),
                      &Point2I(br.x - spc, br.y),
                      colorTable[0 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + spc, br.y - 1),
                      &Point2I(br.x - spc, br.y - 1),
                      colorTable[1 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + spc, br.y - 2),
                      &Point2I(br.x - spc, br.y - 2),
                      BLACK);
      sfc->drawPoint2d(&Point2I(tl.x + spc - 1, br.y - 1), colorTable[0 + colorOffset]);
      sfc->drawPoint2d(&Point2I(br.x - spc + 1, br.y - 1), colorTable[0 + colorOffset]);
                      
      //left edge                
      sfc->drawLine2d(&Point2I(tl.x, tl.y + spc),
                      &Point2I(tl.x, br.y - spc),
                      colorTable[0 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + 1, tl.y + spc),
                      &Point2I(tl.x + 1, br.y - spc),
                      colorTable[1 + colorOffset]);
      sfc->drawLine2d(&Point2I(tl.x + 2, tl.y + spc),
                      &Point2I(tl.x + 2, br.y - spc),
                      BLACK);
      sfc->drawPoint2d(&Point2I(tl.x + 1, tl.y + spc - 1), colorTable[0 + colorOffset]);
      sfc->drawPoint2d(&Point2I(tl.x + 1, br.y - spc + 1), colorTable[0 + colorOffset]);
                      
      //right edge                
      sfc->drawLine2d(&Point2I(br.x, tl.y + spc),
                      &Point2I(br.x, br.y - spc),
                      colorTable[0 + colorOffset]);
      sfc->drawLine2d(&Point2I(br.x - 1, tl.y + spc),
                      &Point2I(br.x - 1, br.y - spc),
                      colorTable[1 + colorOffset]);
      sfc->drawLine2d(&Point2I(br.x - 2, tl.y + spc),
                      &Point2I(br.x - 2, br.y - spc),
                      BLACK);
      sfc->drawPoint2d(&Point2I(br.x - 1, tl.y + spc - 1), colorTable[0 + colorOffset]);
      sfc->drawPoint2d(&Point2I(br.x - 1, br.y - spc + 1), colorTable[0 + colorOffset]);
      
      //inside box
      tl += spc - 1;
      br -= spc - 1;
      sfc->drawRect2d(&RectI(tl.x, tl.y, br.x, br.y), colorTable[2 + colorOffset]);
      tl += 1;
      br -= 1;
      sfc->drawRect2d(&RectI(tl.x, tl.y, br.x, br.y), colorTable[3 + colorOffset]);
      tl += 1;
      br -= 1;
      sfc->drawRect2d(&RectI(tl.x, tl.y, br.x, br.y), BLACK);
   }
   else
   {
      bool prevDisabled = disabled;
      disabled = ghosted;
      Parent::drawBorder(sfc, offset);
      disabled = prevDisabled;
   }
}   
Exemple #20
0
/* static */ bool
H264::DecodeSPS(const mozilla::MediaByteBuffer* aSPS, SPSData& aDest)
{
  MOZ_ASSERT(aSPS);
  BitReader br(aSPS);

  int32_t lastScale;
  int32_t nextScale;
  int32_t deltaScale;

  aDest.profile_idc = br.ReadBits(8);
  aDest.constraint_set0_flag = br.ReadBit();
  aDest.constraint_set1_flag = br.ReadBit();
  aDest.constraint_set2_flag = br.ReadBit();
  aDest.constraint_set3_flag = br.ReadBit();
  aDest.constraint_set4_flag = br.ReadBit();
  aDest.constraint_set5_flag = br.ReadBit();
  br.ReadBits(2); // reserved_zero_2bits
  aDest.level_idc = br.ReadBits(8);
  aDest.seq_parameter_set_id = br.ReadUE();
  if (aDest.profile_idc == 100 || aDest.profile_idc == 110 ||
      aDest.profile_idc == 122 || aDest.profile_idc == 244 ||
      aDest.profile_idc == 44 || aDest.profile_idc == 83 ||
     aDest.profile_idc == 86 || aDest.profile_idc == 118 ||
      aDest.profile_idc == 128 || aDest.profile_idc == 138 ||
      aDest.profile_idc == 139 || aDest.profile_idc == 134) {
    if ((aDest.chroma_format_idc = br.ReadUE()) == 3) {
      aDest.separate_colour_plane_flag = br.ReadBit();
    }
    br.ReadUE();  // bit_depth_luma_minus8
    br.ReadUE();  // bit_depth_chroma_minus8
    br.ReadBit(); // qpprime_y_zero_transform_bypass_flag
    if (br.ReadBit()) { // seq_scaling_matrix_present_flag
      for (int idx = 0; idx < ((aDest.chroma_format_idc != 3) ? 8 : 12); ++idx) {
        if (br.ReadBit()) { // Scaling list present
          lastScale = nextScale = 8;
          int sl_n = (idx < 6) ? 16 : 64;
          for (int sl_i = 0; sl_i < sl_n; sl_i++) {
            if (nextScale) {
              deltaScale = br.ReadSE();
              nextScale = (lastScale + deltaScale + 256) % 256;
            }
            lastScale = (nextScale == 0) ? lastScale : nextScale;
          }
        }
      }
    }
  } else if (aDest.profile_idc == 183) {
      aDest.chroma_format_idc = 0;
  } else {
    // default value if chroma_format_idc isn't set.
    aDest.chroma_format_idc = 1;
  }
  aDest.log2_max_frame_num = br.ReadUE() + 4;
  aDest.pic_order_cnt_type = br.ReadUE();
  if (aDest.pic_order_cnt_type == 0) {
    aDest.log2_max_pic_order_cnt_lsb = br.ReadUE() + 4;
  } else if (aDest.pic_order_cnt_type == 1) {
    aDest.delta_pic_order_always_zero_flag = br.ReadBit();
    aDest.offset_for_non_ref_pic = br.ReadSE();
    aDest.offset_for_top_to_bottom_field = br.ReadSE();
    uint32_t num_ref_frames_in_pic_order_cnt_cycle = br.ReadUE();
    for (uint32_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
      br.ReadSE(); // offset_for_ref_frame[i]
    }
  }
  aDest.max_num_ref_frames = br.ReadUE();
  aDest.gaps_in_frame_num_allowed_flag = br.ReadBit();
  aDest.pic_width_in_mbs = br.ReadUE() + 1;
  aDest.pic_height_in_map_units = br.ReadUE() + 1;
  aDest.frame_mbs_only_flag = br.ReadBit();
  if (!aDest.frame_mbs_only_flag) {
    aDest.pic_height_in_map_units *= 2;
    aDest.mb_adaptive_frame_field_flag = br.ReadBit();
  }
  br.ReadBit(); // direct_8x8_inference_flag
  aDest.frame_cropping_flag = br.ReadBit();
  if (aDest.frame_cropping_flag) {
    aDest.frame_crop_left_offset = br.ReadUE();
    aDest.frame_crop_right_offset = br.ReadUE();
    aDest.frame_crop_top_offset = br.ReadUE();
    aDest.frame_crop_bottom_offset = br.ReadUE();
  }

  aDest.sample_ratio = 1.0f;
  aDest.vui_parameters_present_flag = br.ReadBit();
  if (aDest.vui_parameters_present_flag) {
    vui_parameters(br, aDest);
  }

  // Calculate common values.

  uint8_t ChromaArrayType =
    aDest.separate_colour_plane_flag ? 0 : aDest.chroma_format_idc;
  // Calculate width.
  uint32_t CropUnitX = 1;
  uint32_t SubWidthC = aDest.chroma_format_idc == 3 ? 1 : 2;
  if (ChromaArrayType != 0) {
    CropUnitX = SubWidthC;
  }

  // Calculate Height
  uint32_t CropUnitY = 2 - aDest.frame_mbs_only_flag;
  uint32_t SubHeightC = aDest.chroma_format_idc <= 1 ? 2 : 1;
  if (ChromaArrayType != 0) {
    CropUnitY *= SubHeightC;
  }

  uint32_t width = aDest.pic_width_in_mbs * 16;
  uint32_t height = aDest.pic_height_in_map_units * 16;
  if (aDest.frame_crop_left_offset <= std::numeric_limits<int32_t>::max() / 4 / CropUnitX &&
      aDest.frame_crop_right_offset <= std::numeric_limits<int32_t>::max() / 4 / CropUnitX &&
      aDest.frame_crop_top_offset <= std::numeric_limits<int32_t>::max() / 4 / CropUnitY &&
      aDest.frame_crop_bottom_offset <= std::numeric_limits<int32_t>::max() / 4 / CropUnitY &&
      (aDest.frame_crop_left_offset + aDest.frame_crop_right_offset) * CropUnitX < width &&
      (aDest.frame_crop_top_offset + aDest.frame_crop_bottom_offset) * CropUnitY < height) {
    aDest.crop_left = aDest.frame_crop_left_offset * CropUnitX;
    aDest.crop_right = aDest.frame_crop_right_offset * CropUnitX;
    aDest.crop_top = aDest.frame_crop_top_offset * CropUnitY;
    aDest.crop_bottom = aDest.frame_crop_bottom_offset * CropUnitY;
  } else {
    // Nonsensical value, ignore them.
    aDest.crop_left = aDest.crop_right = aDest.crop_top = aDest.crop_bottom = 0;
  }

  aDest.pic_width = width - aDest.crop_left - aDest.crop_right;
  aDest.pic_height = height - aDest.crop_top - aDest.crop_bottom;

  aDest.interlaced = !aDest.frame_mbs_only_flag;

  // Determine display size.
  if (aDest.sample_ratio > 1.0) {
    // Increase the intrinsic width
    aDest.display_width =
      ConditionDimension(aDest.pic_width * aDest.sample_ratio);
    aDest.display_height = aDest.pic_height;
  } else {
    // Increase the intrinsic height
    aDest.display_width = aDest.pic_width;
    aDest.display_height =
      ConditionDimension(aDest.pic_height / aDest.sample_ratio);
  }

  return true;
}
	/*! @brief create a single bounding box in 3D
	 *
	 * Given an image, its depth correspondences and a candidate,
	 * return an approximate 3D bounding box which encapsulates the object
	 * @param im the color image
	 * @param depth the depth image (may be of different resolution to the color image)
	 * @return
	 */
	Rect3d boundingBox3D(const cv::Mat& im, const cv::Mat& depth) const {

		const size_t nparts = parts_.size();
		const cv::Rect bounds = cv::Rect(0,0,0,0) + im.size();
		const cv::Rect bb  = this->boundingBox();
		const cv::Rect bbn = this->boundingBoxNorm();

		cv::Size_<double> imsize = im.size();
		cv::Size_<double> dsize  = depth.size();
		cv::Point_<double> s = cv::Point_<double>(dsize.width / imsize.width, dsize.height / imsize.height);

		cv::Mat_<float> points;
		std::vector<cv::Rect> boxes;
		for (size_t n = 0; n < nparts; ++n) {
			// only keep the intersection of the part with the image frame
			boxes.push_back(parts_[n] & bounds);
		}
		boxes.push_back(bbn & bounds);

		for (size_t n = 0; n < boxes.size(); ++n) {
			// scale the part down to match the depth image size
			cv::Rect& r = boxes[n];
			r.x = r.x * s.x;
			r.y = r.y * s.y;
			r.width  = r.width  * s.x;
			r.height = r.height * s.y;

			// add the valid points
			cv::Mat_<float> part = depth(r);
			if(part.empty())
				continue;

			for (cv::MatIterator_<float> it = part.begin(); it != part.end(); ++it) {
				if (*it != 0 && !std::isnan(*it)) points.push_back(*it);
			}

			if(points.empty())
			{
				return Rect3d(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(),
						0, 0, 0);
			}

		}

		// sort the points
		std::sort(points.begin(), points.end());
		cv::resize(points, points, cv::Size(1, 400));

		// get the median of the points
		const size_t M = points.rows;
		const size_t midx = M/2;
        // float median = points[midx][0]; // unused variable

		// filter the points
		cv::Mat_<float> g, dog, dpoints;
		cv::Matx<float, 3, 1> diff(-1, 0, 1);
		g= cv::getGaussianKernel(35, 4, CV_32F);
		cv::filter2D(g, dog, -1, diff);
		cv::filter2D(points, dpoints, -1, dog);

		// starting at the median point, walk up and down until a gradient threshold (0.1)
		size_t dminidx = midx, dmaxidx = midx;
		for (size_t m = midx; m < M; ++m) {
			if (fabs(dpoints[m][0]) > 0.035) break;
			dmaxidx = m;
		}
		for (int m = midx; m >= 0; --m) {
			if (fabs(dpoints[m][0]) > 0.035) break;
			dminidx = m;
		}

		// construct the 3D bounding box
		cv::Point3_<double> tl(bb.x,      bb.y,      points[dminidx][0]);
		cv::Point3_<double> br(bb.br().x, bb.br().y, points[dmaxidx][0]);

		return Rect3d(tl, br);
	}
void BTB::StaticDetector::pruneTrainDescriptors(const std::string &path)
{
  matcher.clear();

  std::vector<ProcessedImage> pruningImages;
  std::map<std::string, cv::Rect> pruningImagesExpected;
  for (std::vector<ProcessedImage>::iterator it = processedTrainImages.begin(); it != processedTrainImages.end(); ++it)
  {
      std::string fullImagePath = path + "webcam_" + it->imageNumber + ".png";
      cv::Mat fullImage = cv::imread(fullImagePath);
      if (!fullImage.data)
      {
        throw std::logic_error("error loading image: " + fullImagePath);
      }
      ProcessedImage processedImage(algo, fullImage, it->imageNumber);
      pruningImages.push_back(processedImage);

      std::string motoImagePath = path + it->imageNumber + ".png";
      cv::Mat motoImage = cv::imread(motoImagePath);
      if (!motoImage.data)
      {
        throw std::logic_error("error loading image: " + motoImagePath);
      }
      cv::Point2i p = BTB::findExactMatch(fullImage, motoImage);

      const double factor = 0.3;
      cv::Point2i tl(std::max(p.x - int(motoImage.cols * factor), 0), std::max(p.y - int(motoImage.rows * factor), 0));
      cv::Point2i br(std::min(p.x + int(motoImage.cols * (1 + factor)), fullImage.cols), std::min(p.y + int(motoImage.rows * (1 + factor)), fullImage.rows));
      cv::Rect expected(tl, br);
      pruningImagesExpected.insert(std::pair<std::string, cv::Rect>(it->imageNumber, expected));
  }

  for (std::vector<ProcessedImage>::iterator itTraining = processedTrainImages.begin(); itTraining != processedTrainImages.end(); ++itTraining)
  {
    std::vector<int> prunedKeypoints;

    cv::BFMatcher matcher;
    std::vector<cv::Mat> descriptors;
    descriptors.push_back(itTraining->descriptors);
    matcher.add(descriptors);

    for (std::vector<ProcessedImage>::iterator itPruning = pruningImages.begin(); itPruning != pruningImages.end(); ++itPruning)
    {
      std::vector<cv::DMatch> matches = computeMatches(matcher, *itPruning);
      for (std::vector<cv::DMatch>::iterator itMatches = matches.begin(); itMatches != matches.end(); ++itMatches)
      {
        cv::KeyPoint keypoint = itPruning->keypoints[itMatches->queryIdx];
        cv::Point2i point = keypoint.pt;
        if (!pruningImagesExpected[itPruning->imageNumber].contains(point))
        {
          prunedKeypoints.push_back(itMatches->trainIdx);
        }
      }
    }

    std::vector<cv::KeyPoint> goodKeypoints;
    for (int i = 0; i < itTraining->keypoints.size(); i++)
    {
      if (std::find(prunedKeypoints.begin(), prunedKeypoints.end(), i) == prunedKeypoints.end())
      {
        goodKeypoints.push_back(itTraining->keypoints[i]);
      }
    }

    if (itTraining->pruneKeypoints(goodKeypoints))
    {
      std::vector<cv::Mat> newDescriptors;
      newDescriptors.push_back(itTraining->descriptors);
      this->matcher.add(newDescriptors);
    }
  }
}
Exemple #23
0
void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr )
{
    int x = cr.x();
    int y = cr.y();
    if ( !knownField || knownField->width() != cr.width() ||
	 knownField->height() != cr.height() ) {
	delete knownField;
	knownField = new QPixmap( cr.width(), cr.height() );
	QPainter pp( knownField );
	QBrush br( cg.button().dark(115) );
	qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, TRUE, &br );
    }

    const int pmmarg=cr.width()/5;

    if ( !unknownField || unknownField->width() != cr.width() ||
         unknownField->height() != cr.height() ) {
	delete unknownField;
	unknownField = new QPixmap( cr.width(), cr.height() );
	QPainter pp( unknownField );
	QBrush br( cg.button() );
	qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, FALSE, &br );
    }

    if ( !flag_pix || flag_pix->width() != cr.width()-pmmarg*2 ||
	 flag_pix->height() != cr.height()-pmmarg*2 ) {
	delete flag_pix;
	flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
	flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
    }

    if ( !mine_pix || mine_pix->width() != cr.width()-pmmarg*2 ||
	 mine_pix->height() != cr.height()-pmmarg*2 ) {
	delete mine_pix;
	mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 );
	mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) );
    }

    p->save();

    switch(st) {
    case Hidden:
	p->drawPixmap( x, y, *unknownField );
	break;
    case Empty:
	p->drawPixmap( x, y, *knownField );
	if ( hint > 0 ) {
	    switch( hint ) {
	    case 1:
		p->setPen( blue );
		break;
	    case 2:
		p->setPen( green.dark() );
		break;
	    case 3:
		p->setPen( red );
		break;
	    case 4:
		p->setPen( darkYellow.dark() );
		break;
	    case 5:
		p->setPen( darkMagenta );
		break;
	    case 6:
		p->setPen( darkRed );
		break;
	    default:
		p->setPen( black );
		break;
	    }
	    p->drawText( cr, AlignHCenter | AlignVCenter, QString::number( hint ) );
	}
	break;
    case Mined:
	p->drawPixmap( x, y, *knownField );
	p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix );
	break;
    case Exploded:
	p->drawPixmap( x, y, *knownField );
	p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix );
	p->setPen( red );
	p->drawText( cr, AlignHCenter | AlignVCenter, "X" );
	break;
    case Flagged:
	p->drawPixmap( x, y, *unknownField );
	p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix );
	break;
#ifdef MARK_UNSURE
    case Unsure:
	p->drawPixmap( x, y, *unknownField );
	p->drawText( cr, AlignHCenter | AlignVCenter, "?" );
	break;
#endif
    case Wrong:
	p->drawPixmap( x, y, *unknownField );
	p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix );
	p->setPen( red );
	p->drawText( cr, AlignHCenter | AlignVCenter, "X" );
	break;
    }

    p->restore();
}
  template<class K> typename K::FT intersection_area(const Rectangle_2<K>& a, const Rectangle_2<K> &b) {
    typedef typename K::Vector_2 Vector_2;
    typedef typename K::FT FT;

    if(a.is_degenerate() || b.is_degenerate()) return 0;
        Vector_2 v(b.center()-a.center());
        Vector_2 m(-a.normal().y(),a.normal().x());
        FT n2  = a.normal().squared_length();
        FT m2  = abs(a.ratio())*n2;
    FT br(abs(b.ratio()));
        FT cx = a.normal()*v;
        FT cy = m*v;
        FT nx = a.normal()*b.normal();
        FT ny = m*b.normal();
    switch(sign(nx)) {
    case ZERO : { // m and b.normal() are collinear
        ny = abs(ny);
        FT mx = br*ny;
        FT lx = cx-mx;
        FT rx = cx+mx;
        FT by = cy-ny;
        FT ty = cy+ny;
            if(rx<=-n2 || n2<=lx || ty<=-m2 || m2<=by) return 0;
        return (min(n2,rx)-max(-n2,lx))*(min(m2,ty)-max(-m2,by))/n2;
        }
    case NEGATIVE : // b.normal() =rotate180(b.normal())
        { nx = -nx; ny = -ny; }
    default : ;
    }
        FT mx =-br*ny;
        FT my = br*nx;
    switch(sign(ny)) {
    case ZERO : { // n and b.normal() are collinear
        FT lx = cx-nx;
        FT rx = cx+nx;
        FT by = cy-my;
        FT ty = cy+my;
            if(rx<=-n2 || n2<=lx || ty<=-m2 || m2<=by) return 0;
        return (min(n2,rx)-max(-n2,lx))*(min(m2,ty)-max(-m2,by))/n2;
        }
    case NEGATIVE : // b.normal() =rotate90(b.normal())
        nx = -nx; std::swap(nx,mx);
        ny = -ny; std::swap(ny,my);
    default : { // nx>0, ny>0, mx<0 and my>0 case
        FT sumx(nx+mx), sumy(ny+my);
        FT difx(nx-mx), dify(ny-my);
        FT x[] = { cx-sumx, cx+difx, cx+sumx, cx-difx }; // bottom, right, top, left
        FT y[] = { cy-sumy, cy+dify, cy+sumy, cy-dify };
            if(y[0]>=m2 || y[2]<=-m2 || x[3]>=n2 || x[1]<=-n2) return 0; // one edge of "this" separates the 2 rectangles
        FT area =  Impl::triangle_area(n2, m2, x[2], y[2], x[1], y[1])
            +  Impl::triangle_area(m2, n2, y[3],-x[3], y[2],-x[2])
            +  Impl::triangle_area(n2, m2,-x[0],-y[0],-x[3],-y[3])
            +  Impl::triangle_area(m2, n2,-y[1], x[1],-y[0], x[0]);
        // iso-rectangle area
        FT lx = x[0], by = y[1];
        FT rx = x[2], ty = y[3];
        FT s  = 1;
        if(lx>rx) { std::swap(lx,rx); s=-s; }
        if(by>ty) { std::swap(by,ty); s=-s; }
        if(by>=m2 || ty<=-m2 || lx>=n2 || rx<=-n2) return area/n2;
        return (area + s*(min(n2,rx)-max(-n2,lx))*(min(m2,ty)-max(-m2,by)))/n2;
    }
    }

}
void PatchingStub::emit_code(LIR_Assembler* ce) {
  // copy original code here
  assert(NativeCall::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF,
         "not enough room for call");
  assert((_bytes_to_copy & 0x3) == 0, "must copy a multiple of four bytes");

  Label call_patch;

  int being_initialized_entry = __ offset();

  if (_id == load_klass_id) {
    // produce a copy of the load klass instruction for use by the being initialized case
#ifdef ASSERT
    address start = __ pc();
#endif
    AddressLiteral addrlit(NULL, metadata_Relocation::spec(_index));
    __ patchable_set(addrlit, _obj);

#ifdef ASSERT
    for (int i = 0; i < _bytes_to_copy; i++) {
      address ptr = (address)(_pc_start + i);
      int a_byte = (*ptr) & 0xFF;
      assert(a_byte == *start++, "should be the same code");
    }
#endif
  } else if (_id == load_mirror_id || _id == load_appendix_id) {
    // produce a copy of the load mirror instruction for use by the being initialized case
#ifdef ASSERT
    address start = __ pc();
#endif
    AddressLiteral addrlit(NULL, oop_Relocation::spec(_index));
    __ patchable_set(addrlit, _obj);

#ifdef ASSERT
    for (int i = 0; i < _bytes_to_copy; i++) {
      address ptr = (address)(_pc_start + i);
      int a_byte = (*ptr) & 0xFF;
      assert(a_byte == *start++, "should be the same code");
    }
#endif
  } else {
    // make a copy the code which is going to be patched.
    for (int i = 0; i < _bytes_to_copy; i++) {
      address ptr = (address)(_pc_start + i);
      int a_byte = (*ptr) & 0xFF;
      __ emit_int8 (a_byte);
    }
  }

  address end_of_patch = __ pc();
  int bytes_to_skip = 0;
  if (_id == load_mirror_id) {
    int offset = __ offset();
    if (CommentedAssembly) {
      __ block_comment(" being_initialized check");
    }

    // static field accesses have special semantics while the class
    // initializer is being run so we emit a test which can be used to
    // check that this code is being executed by the initializing
    // thread.
    assert(_obj != noreg, "must be a valid register");
    assert(_index >= 0, "must have oop index");
    __ ld_ptr(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
    __ ld_ptr(G3, in_bytes(InstanceKlass::init_thread_offset()), G3);
    __ cmp_and_brx_short(G2_thread, G3, Assembler::notEqual, Assembler::pn, call_patch);

    // load_klass patches may execute the patched code before it's
    // copied back into place so we need to jump back into the main
    // code of the nmethod to continue execution.
    __ br(Assembler::always, false, Assembler::pt, _patch_site_continuation);
    __ delayed()->nop();

    // make sure this extra code gets skipped
    bytes_to_skip += __ offset() - offset;
  }

  // Now emit the patch record telling the runtime how to find the
  // pieces of the patch.  We only need 3 bytes but it has to be
  // aligned as an instruction so emit 4 bytes.
  int sizeof_patch_record = 4;
  bytes_to_skip += sizeof_patch_record;

  // emit the offsets needed to find the code to patch
  int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record;

  // Emit the patch record.  We need to emit a full word, so emit an extra empty byte
  __ emit_int8(0);
  __ emit_int8(being_initialized_entry_offset);
  __ emit_int8(bytes_to_skip);
  __ emit_int8(_bytes_to_copy);
  address patch_info_pc = __ pc();
  assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info");

  address entry = __ pc();
  NativeGeneralJump::insert_unconditional((address)_pc_start, entry);
  address target = NULL;
  relocInfo::relocType reloc_type = relocInfo::none;
  switch (_id) {
    case access_field_id:  target = Runtime1::entry_for(Runtime1::access_field_patching_id); break;
    case load_klass_id:    target = Runtime1::entry_for(Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break;
    case load_mirror_id:   target = Runtime1::entry_for(Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break;
    case load_appendix_id: target = Runtime1::entry_for(Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break;
    default: ShouldNotReachHere();
  }
  __ bind(call_patch);

  if (CommentedAssembly) {
    __ block_comment("patch entry point");
  }
  __ call(target, relocInfo::runtime_call_type);
  __ delayed()->nop();
  assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change");
  ce->add_call_info_here(_info);
  __ br(Assembler::always, false, Assembler::pt, _patch_site_entry);
  __ delayed()->nop();
  if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
    CodeSection* cs = __ code_section();
    address pc = (address)_pc_start;
    RelocIterator iter(cs, pc, pc + 1);
    relocInfo::change_reloc_info_for_address(&iter, (address) pc, reloc_type, relocInfo::none);

    pc = (address)(_pc_start + NativeMovConstReg::add_offset);
    RelocIterator iter2(cs, pc, pc+1);
    relocInfo::change_reloc_info_for_address(&iter2, (address) pc, reloc_type, relocInfo::none);
  }

}
void QWSDefaultDecoration::paint(QPainter *painter, const QWidget *widget)
{
#ifndef QT_NO_STYLE
    QStyle &style = QApplication::style();
#endif

    int titleWidth = getTitleWidth(widget);
    int titleHeight = getTitleHeight(widget);

    QRect rect(widget->rect());

    // Border rect
    QRect br( rect.left() - BORDER_WIDTH,
                rect.top() - BORDER_WIDTH - titleHeight,
                rect.width() + 2 * BORDER_WIDTH,
                rect.height() + BORDER_WIDTH + BOTTOM_BORDER_WIDTH + titleHeight );

    // title bar rect
    QRect tr;

    {
        tr = QRect( titleHeight, -titleHeight,  titleWidth, titleHeight - 1);
    }

    QRegion oldClip = painter->clipRegion();
    painter->setClipRegion( oldClip - QRegion( tr ) );	// reduce flicker

#ifndef QT_NO_PALETTE
    // const QColorGroup &cg = QApplication::palette().active();
    const QColorGroup &cg = widget->palette().active();

#if !defined(QT_NO_STYLE)
    style.drawPanel(painter, br.x(), br.y(), br.width(),
		    br.height() - 4, cg, FALSE, 2,
		    &cg.brush(QColorGroup::Background));
#elif !defined(QT_NO_DRAWUTIL)
    qDrawWinPanel(painter, br.x(), br.y(), br.width(),
		  br.height() - 4, cg, FALSE,
		  &cg.brush(QColorGroup::Background));
#endif

    painter->setClipRegion( oldClip );

    if (titleWidth > 0) {
	QBrush titleBrush;
	QPen   titlePen;
	int    titleLeft = titleHeight + 4;

	if (widget == qApp->activeWindow()) {
	    titleBrush = cg.brush(QColorGroup::Highlight);
	    titlePen   = cg.color(QColorGroup::HighlightedText);
	} else {
	    titleBrush = cg.brush(QColorGroup::Background);
	    titlePen   = cg.color(QColorGroup::Text);
	}

#define CLAMP(x, y)	    ( ((x) > (y)) ? (y) : (x) )

	{

#if !defined(QT_NO_STYLE)
	    style.drawPanel(painter, tr.x(), tr.y(), tr.width(), tr.height(),
			    cg, TRUE, 1, &titleBrush);
#elif !defined(QT_NO_DRAWUTIL)
	    qDrawWinPanel(painter, tr.x(), tr.y(), tr.width(), tr.height(),
			    cg, TRUE, &titleBrush);
#endif

	    painter->setPen(titlePen);
	    painter->setFont(widget->font());
	    painter->drawText( titleLeft, -titleHeight,
			    titleWidth-5, titleHeight - 1,
			    QPainter::AlignVCenter, widget->caption());
	    return;
	}

	painter->setPen(titlePen);
	painter->setFont(widget->font());
	painter->drawText( titleLeft, -titleHeight,
	 		rect.width() - titleHeight - 10, titleHeight-1,
			QPainter::AlignVCenter, widget->caption());
    }

#endif //QT_NO_PALETTE

}
Exemple #27
0
Stitcher::Status Stitcher::matchImages()
{
    if ((int)imgs_.size() < 2)
    {
        LOGLN("Need more images");
        return ERR_NEED_MORE_IMGS;
    }

    work_scale_ = 1;
    seam_work_aspect_ = 1;
    seam_scale_ = 1;
    bool is_work_scale_set = false;
    bool is_seam_scale_set = false;
    Mat full_img, img;
    features_.resize(imgs_.size());
    seam_est_imgs_.resize(imgs_.size());
    full_img_sizes_.resize(imgs_.size());

    LOGLN("Finding features...");
#if ENABLE_LOG
    int64 t = getTickCount();
#endif

    for (size_t i = 0; i < imgs_.size(); ++i)
    {
        full_img = imgs_[i];
        full_img_sizes_[i] = full_img.size();

        if (registr_resol_ < 0)
        {
            img = full_img;
            work_scale_ = 1;
            is_work_scale_set = true;
        }
        else
        {
            if (!is_work_scale_set)
            {
                work_scale_ = std::min(1.0, std::sqrt(registr_resol_ * 1e6 / full_img.size().area()));
                is_work_scale_set = true;
            }
            resize(full_img, img, Size(), work_scale_, work_scale_);
        }
        if (!is_seam_scale_set)
        {
            seam_scale_ = std::min(1.0, std::sqrt(seam_est_resol_ * 1e6 / full_img.size().area()));
            seam_work_aspect_ = seam_scale_ / work_scale_;
            is_seam_scale_set = true;
        }

        if (rois_.empty())
            (*features_finder_)(img, features_[i]);
        else
        {
            std::vector<Rect> rois(rois_[i].size());
            for (size_t j = 0; j < rois_[i].size(); ++j)
            {
                Point tl(cvRound(rois_[i][j].x * work_scale_), cvRound(rois_[i][j].y * work_scale_));
                Point br(cvRound(rois_[i][j].br().x * work_scale_), cvRound(rois_[i][j].br().y * work_scale_));
                rois[j] = Rect(tl, br);
            }
            (*features_finder_)(img, features_[i], rois);
        }
        features_[i].img_idx = (int)i;
        LOGLN("Features in image #" << i+1 << ": " << features_[i].keypoints.size());

        resize(full_img, img, Size(), seam_scale_, seam_scale_);
        seam_est_imgs_[i] = img.clone();
    }

    // Do it to save memory
    features_finder_->collectGarbage();
    full_img.release();
    img.release();

    LOGLN("Finding features, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");

    LOG("Pairwise matching");
#if ENABLE_LOG
    t = getTickCount();
#endif
    (*features_matcher_)(features_, pairwise_matches_, matching_mask_);
    features_matcher_->collectGarbage();
    LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");

    // Leave only images we are sure are from the same panorama
    indices_ = detail::leaveBiggestComponent(features_, pairwise_matches_, (float)conf_thresh_);
    std::vector<Mat> seam_est_imgs_subset;
    std::vector<Mat> imgs_subset;
    std::vector<Size> full_img_sizes_subset;
    for (size_t i = 0; i < indices_.size(); ++i)
    {
        imgs_subset.push_back(imgs_[indices_[i]]);
        seam_est_imgs_subset.push_back(seam_est_imgs_[indices_[i]]);
        full_img_sizes_subset.push_back(full_img_sizes_[indices_[i]]);
    }
    seam_est_imgs_ = seam_est_imgs_subset;
    imgs_ = imgs_subset;
    full_img_sizes_ = full_img_sizes_subset;

    if ((int)imgs_.size() < 2)
    {
        LOGLN("Need more images");
        return ERR_NEED_MORE_IMGS;
    }

    return OK;
}
Exemple #28
0
void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,
                                          const QBrush &fillBrush,
                                          const QPen &linePen, int alpha)
{
    int lineWidth = linePen.width();
    int halfline  = lineWidth / 2;
    int rad = cornerRadius - halfline;

    if ((area.width() / 2) < rad)
        rad = area.width() / 2;

    if ((area.height() / 2) < rad)
        rad = area.height() / 2;
    int dia = rad * 2;


    QRect r(area.left() + halfline, area.top() + halfline,
            area.width() - (halfline * 2), area.height() - (halfline * 2));

    QRect tl(r.left(),  r.top(), rad, rad);
    QRect tr(r.left() + r.width() - rad, r.top(), rad, rad);
    QRect bl(r.left(),  r.top() + r.height() - rad, rad, rad);
    QRect br(r.left() + r.width() - rad, r.top() + r.height() - rad, rad, rad);

    SetBlend(true);
    DisableTextures();

    m_glEnableVertexAttribArray(VERTEX_INDEX);

    if (fillBrush.style() != Qt::NoBrush)
    {
        // Get the shaders
        int elip = m_shaders[kShaderCircle];
        int fill = m_shaders[kShaderSimple];

        // Set the fill color
        m_glVertexAttrib4f(COLOR_INDEX,
                           fillBrush.color().red() / 255.0,
                           fillBrush.color().green() / 255.0,
                           fillBrush.color().blue() / 255.0,
                          (fillBrush.color().alpha() / 255.0) * (alpha / 255.0));

        // Set the radius
        m_parameters[0][2] = rad;
        m_parameters[0][3] = rad - 1.0;

        // Enable the Circle shader
        SetShaderParams(elip, &m_projection[0][0], "u_projection");

        // Draw the top left segment
        m_parameters[0][0] = tl.left() + rad;
        m_parameters[0][1] = tl.top() + rad;
        SetShaderParams(elip, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, tl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the top right segment
        m_parameters[0][0] = tr.left();
        m_parameters[0][1] = tr.top() + rad;
        SetShaderParams(elip, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, tr);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the bottom left segment
        m_parameters[0][0] = bl.left() + rad;
        m_parameters[0][1] = bl.top();
        SetShaderParams(elip, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, bl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the bottom right segment
        m_parameters[0][0] = br.left();
        m_parameters[0][1] = br.top();
        SetShaderParams(elip, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, br);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Fill the remaining areas
        QRect main(r.left() + rad, r.top(), r.width() - dia, r.height());
        QRect left(r.left(), r.top() + rad, rad, r.height() - dia);
        QRect right(r.left() + r.width() - rad, r.top() + rad, rad, r.height() - dia);

        EnableShaderObject(fill);
        SetShaderParams(fill, &m_projection[0][0], "u_projection");

        GetCachedVBO(GL_TRIANGLE_STRIP, main);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        GetCachedVBO(GL_TRIANGLE_STRIP, left);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        GetCachedVBO(GL_TRIANGLE_STRIP, right);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        m_glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    if (linePen.style() != Qt::NoPen)
    {
        // Get the shaders
        int edge = m_shaders[kShaderCircleEdge];
        int vline = m_shaders[kShaderVertLine];
        int hline = m_shaders[kShaderHorizLine];

        // Set the line color
        m_glVertexAttrib4f(COLOR_INDEX,
                           linePen.color().red() / 255.0,
                           linePen.color().green() / 255.0,
                           linePen.color().blue() / 255.0,
                          (linePen.color().alpha() / 255.0) * (alpha / 255.0));

        // Set the radius and width
        m_parameters[0][2] = rad - lineWidth / 2.0;
        m_parameters[0][3] = lineWidth / 2.0;

        // Enable the edge shader
        SetShaderParams(edge, &m_projection[0][0], "u_projection");

        // Draw the top left edge segment
        m_parameters[0][0] = tl.left() + rad;
        m_parameters[0][1] = tl.top() + rad;
        SetShaderParams(edge, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, tl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the top right edge segment
        m_parameters[0][0] = tr.left();
        m_parameters[0][1] = tr.top() + rad;
        SetShaderParams(edge, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, tr);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the bottom left edge segment
        m_parameters[0][0] = bl.left() + rad;
        m_parameters[0][1] = bl.top();
        SetShaderParams(edge, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, bl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the bottom right edge segment
        m_parameters[0][0] = br.left();
        m_parameters[0][1] = br.top();
        SetShaderParams(edge, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, br);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Vertical lines
        SetShaderParams(vline, &m_projection[0][0], "u_projection");
        m_parameters[0][1] = lineWidth / 2.0;
        QRect vl(r.left(), r.top() + rad,
                 lineWidth, r.height() - dia);

        // Draw the left line segment
        m_parameters[0][0] = vl.left() + lineWidth;
        SetShaderParams(vline, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, vl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the right line segment
        vl.translate(r.width() - lineWidth, 0);
        m_parameters[0][0] = vl.left();
        SetShaderParams(vline, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, vl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Horizontal lines
        SetShaderParams(hline, &m_projection[0][0], "u_projection");
        QRect hl(r.left() + rad, r.top(),
                 r.width() - dia, lineWidth);

        // Draw the top line segment
        m_parameters[0][0] = hl.top() + lineWidth;
        SetShaderParams(hline, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, hl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        // Draw the bottom line segment
        hl.translate(0, r.height() - lineWidth);
        m_parameters[0][0] = hl.top();
        SetShaderParams(hline, &m_parameters[0][0], "u_parameters");
        GetCachedVBO(GL_TRIANGLE_STRIP, hl);
        m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
                                VERTEX_SIZE * sizeof(GLfloat),
                               (const void *) kVertexOffset);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        m_glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    m_glDisableVertexAttribArray(VERTEX_INDEX);
}
void DepthImageSensor::drawPhysics(unsigned int flags) const
{
  glPushMatrix();
  glMultMatrixf(transformation);

  if(flags & SimRobotCore2::Renderer::showSensors)
  {
    Vector3<> ml;
    if(projection == perspectiveProjection)
      ml = Vector3<> (max, -tanf(angleX * 0.5f) * max, 0);
    else
      ml = Vector3<>(cosf(angleX * 0.5f) * max, -sinf(angleX * 0.5f) * max, 0);
    Vector3<> mt(ml.x, 0, tanf(angleY * 0.5f) * max);
    Vector3<> tl(ml.x, ml.y, mt.z);
    Vector3<> tr(ml.x, -ml.y, mt.z);
    Vector3<> bl(ml.x, ml.y, -mt.z);
    Vector3<> br(ml.x, -ml.y, -mt.z);


    glBegin(GL_LINE_LOOP);
      glColor3f(0, 0, 0.5f);
      glNormal3f (0, 0, 1.f);

      unsigned segments = int(18 * angleX / M_PI);
      if(projection == perspectiveProjection && segments > 0)
      {
        glVertex3f(tl.x, tl.y, tl.z);
        glVertex3f(tr.x, tr.y, tr.z);
        glVertex3f(br.x, br.y, br.z);
      }
      else
      {
        float rotX = cosf(angleX / float(segments));
        float rotY = sinf(angleX / float(segments));
        float x = tl.x;
        float y = tl.y;
        for(unsigned int i = 0; i < segments; ++i)
        {
          glVertex3f(x, y, tl.z);
          float x2 = x * rotX - y * rotY;
          y = y * rotX + x * rotY;
          x = x2;
        }
        glVertex3f(tr.x, tr.y, tr.z);
        for(unsigned int i = 0; i < segments; ++i)
        {
          glVertex3f(x, y, br.z);
          float x2 = x * rotX + y * rotY;
          y = y * rotX - x * rotY;
          x = x2;
        }
      }

      glVertex3f(bl.x, bl.y, bl.z);
    glEnd();
    glBegin(GL_LINE_STRIP);
      glVertex3f(tl.x, tl.y, tl.z);
      glVertex3f(0.f, 0.f, 0.f);
      glVertex3f(tr.x, tr.y, tr.z);
    glEnd();
    glBegin(GL_LINE_STRIP);
      glVertex3f(bl.x, bl.y, bl.z);
      glVertex3f(0.f, 0.f, 0.f);
      glVertex3f(br.x, br.y, br.z);
    glEnd();
  }

  Sensor::drawPhysics(flags);

  glPopMatrix();

}
Exemple #30
0
// The address returned here will only be valid until next time this function is called.
// The program is return bound.
QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog)
{
    for (int i = 0; i < cachedPrograms.size(); ++i) {
        QGLEngineShaderProg *cachedProg = cachedPrograms[i];
        if (*cachedProg == prog) {
            // Move the program to the top of the list as a poor-man's cache algo
            cachedPrograms.move(i, 0);
            cachedProg->program->bind();
            return cachedProg;
        }
    }

    QGLShader *vertexShader = 0;
    QGLShader *fragShader = 0;
    QGLEngineShaderProg *newProg = 0;
    bool success = false;

    do {
        QByteArray source;
        // Insert the custom stage before the srcPixel shader to work around an ATI driver bug
        // where you cannot forward declare a function that takes a sampler as argument.
        if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
            source.append(prog.customStageSource);
        source.append(qShaderSnippets[prog.mainFragShader]);
        source.append(qShaderSnippets[prog.srcPixelFragShader]);
        if (prog.compositionFragShader)
            source.append(qShaderSnippets[prog.compositionFragShader]);
        if (prog.maskFragShader)
            source.append(qShaderSnippets[prog.maskFragShader]);
        fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this);
        QByteArray description;
#if defined(QT_DEBUG)
        // Name the shader for easier debugging
        description.append("Fragment shader: main=");
        description.append(snippetNameStr(prog.mainFragShader));
        description.append(", srcPixel=");
        description.append(snippetNameStr(prog.srcPixelFragShader));
        if (prog.compositionFragShader) {
            description.append(", composition=");
            description.append(snippetNameStr(prog.compositionFragShader));
        }
        if (prog.maskFragShader) {
            description.append(", mask=");
            description.append(snippetNameStr(prog.maskFragShader));
        }
        fragShader->setObjectName(QString::fromLatin1(description));
#endif
        if (!fragShader->compileSourceCode(source)) {
            qWarning() << "Warning:" << description << "failed to compile!";
            break;
        }

        source.clear();
        source.append(qShaderSnippets[prog.mainVertexShader]);
        source.append(qShaderSnippets[prog.positionVertexShader]);
        vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this);
#if defined(QT_DEBUG)
        // Name the shader for easier debugging
        description.clear();
        description.append("Vertex shader: main=");
        description.append(snippetNameStr(prog.mainVertexShader));
        description.append(", position=");
        description.append(snippetNameStr(prog.positionVertexShader));
        vertexShader->setObjectName(QString::fromLatin1(description));
#endif
        if (!vertexShader->compileSourceCode(source)) {
            qWarning() << "Warning:" << description << "failed to compile!";
            break;
        }

        newProg = new QGLEngineShaderProg(prog);

        // If the shader program's not found in the cache, create it now.
        newProg->program = new QGLShaderProgram(ctxGuard.context(), this);
        newProg->program->addShader(vertexShader);
        newProg->program->addShader(fragShader);

        // We have to bind the vertex attribute names before the program is linked:
        newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
        if (newProg->useTextureCoords)
            newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
        if (newProg->useOpacityAttribute)
            newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
        if (newProg->usePmvMatrixAttribute) {
            newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
            newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
            newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR);
        }

        newProg->program->link();
        if (!newProg->program->isLinked()) {
            QLatin1String none("none");
            QLatin1String br("\n");
            QString error;
            error = QLatin1String("Shader program failed to link,")
#if defined(QT_DEBUG)
                + br
                + QLatin1String("  Shaders Used:") + br
                + QLatin1String("    ") + vertexShader->objectName() + QLatin1String(": ") + br
                + QLatin1String(vertexShader->sourceCode()) + br
                + QLatin1String("    ") + fragShader->objectName() + QLatin1String(": ") + br
                + QLatin1String(fragShader->sourceCode()) + br
#endif
                + QLatin1String("  Error Log:\n")
                + QLatin1String("    ") + newProg->program->log();
            qWarning() << error;
            break;
        }

        newProg->program->bind();

        if (newProg->maskFragShader != QGLEngineSharedShaders::NoMaskFragmentShader) {
            GLuint location = newProg->program->uniformLocation("maskTexture");
            newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT);
        }

        if (cachedPrograms.count() > 30) {
            // The cache is full, so delete the last 5 programs in the list.
            // These programs will be least used, as a program us bumped to
            // the top of the list when it's used.
            for (int i = 0; i < 5; ++i) {
                delete cachedPrograms.last();
                cachedPrograms.removeLast();
            }
        }

        cachedPrograms.insert(0, newProg);

        success = true;
    } while (false);

    // Clean up everything if we weren't successful
    if (!success) {
        if (newProg) {
            delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders
            newProg = 0;
        }
        else {
            if (vertexShader)
                delete vertexShader;
            if (fragShader)
                delete fragShader;
        }
    }

    return newProg;
}