Пример #1
0
void CTransmuterSession::OnPaint(CG32bitImage &Screen, const RECT &rcInvalid)
	{
	//	paint the background
	Screen.Fill(0, 0, Screen.GetWidth(), Screen.GetHeight(), CG32bitPixel(32, 32, 32));

	//	make sure m_SubSessions is up-to-date with any error sessions
	UpdateSubSessionsList();

	//	call paint functions of all subsessions
	for (int i = 0; i < m_SubSessions.GetCount(); i++)
		{
		m_SubSessions[i]->OnPaint(Screen, rcInvalid);
		}
	}
Пример #2
0
CGlowingRingPainter::CGlowingRingPainter (CG32bitImage &Dest, int iRadius, int iWidth, const TArray<CG32bitPixel> &ColorRamp, BYTE byOpacity) :
		m_Dest(Dest),
		m_rcClip(Dest.GetClipRect()),
		m_iRadius(iRadius),
		m_iWidth(iWidth)

//	CGlowingRingPainter constructor

	{
	int i;

	//	Pre-multiply the color ramp

	m_ColorRamp.InsertEmpty(ColorRamp.GetCount());
	m_pColorRamp = &m_ColorRamp;

	if (byOpacity == 0xff)
		{
		for (i = 0; i < m_ColorRamp.GetCount(); i++)
			m_ColorRamp[i] = CG32bitPixel::PreMult(ColorRamp[i]);
		}
	else
		{
		for (i = 0; i < m_ColorRamp.GetCount(); i++)
			{
			CG32bitPixel rgbPreMult = CG32bitPixel::PreMult(ColorRamp[i]);
			m_ColorRamp[i] = CG32bitPixel(CG32bitPixel::Blend(0, rgbPreMult, byOpacity), CG32bitPixel::BlendAlpha(rgbPreMult.GetAlpha(), byOpacity));
			}
		}
	}
Пример #3
0
void CGTextArea::Paint (CG32bitImage &Dest, const RECT &rcRect)

//	Paint
//
//	Handle paint

	{
	RECT rcText = CalcTextRect(rcRect);

	//	Paint the background

	if (m_iBorderRadius > 0)
		CGDraw::RoundedRect(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_iBorderRadius, m_rgbBackColor);
	else
		Dest.Fill(rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_rgbBackColor);

	//	Paint the editable box

	if (m_bEditable)
		{
		CG32bitPixel rgbBorderColor = CG32bitPixel::Blend(CG32bitPixel(0, 0, 0), m_rgbColor, (BYTE)128);
		CGDraw::RectOutlineDotted(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), rgbBorderColor);
		}

	//	Paint the content

	if (!m_sText.IsBlank())
		PaintText(Dest, rcText);
	else
		PaintRTF(Dest, rcText);
	}
Пример #4
0
CGlowingRingPainter::CGlowingRingPainter (CG32bitImage &Dest, int iRadius, int iWidth, CG32bitPixel rgbColor) :
		m_Dest(Dest),
		m_rcClip(Dest.GetClipRect()),
		m_iRadius(iRadius),
		m_iWidth(iWidth)

//	CGlowingRingPainter constructor

	{
	int i;

	if (m_iWidth <= 0)
		{
		m_pColorRamp = NULL;
		return;
		}

	//	Generate a color ramp

	int iCenter = m_iWidth / 2;
	int iExtra = m_iWidth % 2;
	int iOuter = iCenter - 1;
	int iInner = iCenter + iExtra;

	m_ColorRamp.InsertEmpty(m_iWidth);

	//	We expect the color ramp to be pre-multiplied

	CG32bitPixel rgbPreMult = CG32bitPixel::PreMult(rgbColor);

	//	Init the center

	if (iExtra)
		m_ColorRamp[iCenter] = rgbPreMult;

	//	Edges

	for (i = 0; i < iCenter; i++)
		{
		ASSERT(iOuter >= 0 && iOuter < m_iWidth);
		ASSERT(iInner >=0 && iInner < m_iWidth);

		BYTE byAlpha = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetAlpha() * (iCenter - i) / (iCenter + 1)));
		BYTE byRed = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetRed() * (iCenter - i) / (iCenter + 1)));
		BYTE byGreen = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetGreen() * (iCenter - i) / (iCenter + 1)));
		BYTE byBlue = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetBlue() * (iCenter - i) / (iCenter + 1)));

		m_ColorRamp[iOuter] = CG32bitPixel(byRed, byGreen, byBlue, byAlpha);
		m_ColorRamp[iInner] = CG32bitPixel(byRed, byGreen, byBlue, byAlpha);

		iOuter--;
		iInner++;
		}

	m_pColorRamp = &m_ColorRamp;
	}
Пример #5
0
void CSystemMap::GetBackgroundImageSize (int *retcx, int *retcy)

//	GetBackgroundImageSize
//
//	Returns the size of the background image

	{
	CG32bitImage *pImage = g_pUniverse->GetLibraryBitmap(m_dwBackgroundImage);
	if (pImage)
		{
		*retcx = pImage->GetWidth();
		*retcy = pImage->GetHeight();
		}
	else
		{
		*retcx = 0;
		*retcy = 0;
		}
	}
Пример #6
0
void CGalacticMapSession::OnPaint (CG32bitImage &Screen, const RECT &rcInvalid)

//	OnPaint
//
//	Paint

	{
	int cxScreen = Screen.GetWidth();
	int cyScreen = Screen.GetHeight();

	const CVisualPalette &VI = m_HI.GetVisuals();
	CG32bitPixel rgbBackgroundColor = VI.GetColor(colorAreaDeep);
	CG32bitPixel rgbLineColor = VI.GetColor(colorLineFrame);
	const CG16bitFont &HeaderFont = VI.GetFont(fontHeader);
	const CG16bitFont &MediumFont = VI.GetFont(fontMedium);

	//	Paint the actual map

	if (m_pPainter)
		{
		m_pPainter->Paint(Screen);

		//	Paint the ship

		CSpaceObject *pPlayer = g_pUniverse->GetPlayerShip();
		if (pPlayer)
			{
			int xPos, yPos;
			g_pUniverse->GetCurrentSystem()->GetTopology()->GetDisplayPos(&xPos, &yPos);

			int xShip, yShip;
			m_pPainter->GalacticToView(xPos, yPos, m_xCenter, m_yCenter, m_Scale.GetScale(), &xShip, &yShip);

			pPlayer->PaintMap(CMapViewportCtx(), Screen, xShip, yShip);
			}
		}

	//	Paint some help text

    m_HelpPainter.Paint(Screen, 
            m_rcView.left + SCREEN_BORDER_X, 
            m_rcView.bottom - (SCREEN_BORDER_Y + m_HelpPainter.GetHeight()));
	}
Пример #7
0
void DrawLaserBeam (CG32bitImage &Dest, const SBeamDrawCtx &Ctx)

//	DrawLaserBeam
//
//	Draws a simple laser beam

{
    CG32bitPixel rgbGlow = CG32bitPixel(Ctx.rgbSecondaryColor, 100);

    Dest.DrawLine(Ctx.xFrom, Ctx.yFrom,
                  Ctx.xTo, Ctx.yTo,
                  3,
                  rgbGlow);

    Dest.DrawLine(Ctx.xFrom, Ctx.yFrom,
                  Ctx.xTo, Ctx.yTo,
                  1,
                  Ctx.rgbPrimaryColor);
}
Пример #8
0
void CExtensionNavigatorMenuItem::OnPaint(CG32bitImage &Screen, const RECT &rcInvalid)
	{
	//  may remove panel outlining in future
	DrawPanelOutline(Screen);

	int xO = m_AssociatedPanel.GetOriginX();
	int yO = m_AssociatedPanel.GetOriginY();
	int SpaceWidth = m_AssociatedPanel.GetSpaceWidth();
	int SpaceHeight = m_AssociatedPanel.GetSpaceHeight();

	Screen.DrawText(m_AssociatedPanel.GetOriginX() + 10, m_AssociatedPanel.GetOriginY() + 10, m_HeadingFont, m_HeadingColor, m_Extension.GetName());
	}
Пример #9
0
void CGameSession::PaintInfoText (CG32bitImage &Dest, const CString &sTitle, const TArray<CString> &Body, bool bAboveTargeting)

//	PaintInfoText
//
//	Paints info text on the screen

	{
	int i;

	const CVisualPalette &VI = m_HI.GetVisuals();
	const CG16bitFont &TitleFont = VI.GetFont(fontHeader);
	const CG16bitFont &BodyFont = VI.GetFont(fontMedium);

	int x = m_rcScreen.left + 2 * TitleFont.GetAverageWidth();
	int cy = TitleFont.GetHeight() + Body.GetCount() * BodyFont.GetHeight();
	int cySpacing = BodyFont.GetHeight() / 2;

    RECT rcCenter;
    m_HUD.GetClearHorzRect(&rcCenter);
	int y = (bAboveTargeting ? rcCenter.bottom : m_rcScreen.bottom) - (cy + cySpacing);

	Dest.DrawText(x,
			y,
			TitleFont,
			VI.GetColor(colorTextHighlight),
			sTitle);
	y += TitleFont.GetHeight();

	//	Paint the body

	for (i = 0; i < Body.GetCount(); i++)
		{
		Dest.DrawText(x,
				y,
				BodyFont,
				VI.GetColor(colorTextDialogLabel),
				Body[i]);
		y += BodyFont.GetHeight();
		}
	}
Пример #10
0
void CopyGalacticMapToClipboard (HWND hWnd, CGalacticMapPainter *pPainter)
	{
    //  Save some parameters

    RECT rcOldView = pPainter->GetViewport();
    int xOldCenter, yOldCenter;
    pPainter->GetPos(&xOldCenter, &yOldCenter);
    int iOldScale = pPainter->GetScale();

	//	Compute the size of the map

	RECT rcView;
	rcView.left = 0;
	rcView.top = 0;
	rcView.right = pPainter->GetWidth();
	rcView.bottom = pPainter->GetHeight();

	//	Create a bitmap of the appropriate size

	CG32bitImage FullMap;
	FullMap.Create(RectWidth(rcView), RectHeight(rcView));

	//	Paint

    pPainter->SetViewport(rcView);
    pPainter->SetScale(100);
    pPainter->SetPos(0, 0);
	pPainter->Paint(FullMap);

	//	Copy to cliboard

	FullMap.CopyToClipboard();

    //  Restore

    pPainter->SetScale(iOldScale);
    pPainter->SetViewport(rcOldView);
    pPainter->SetPos(xOldCenter, yOldCenter);
	}
Пример #11
0
void CGImageArea::Paint (CG32bitImage &Dest, const RECT &rcRect)

//	Paint
//
//	Handle paint

	{
	if (!m_bTransBackground)
		Dest.Fill(rcRect.left,
				rcRect.top,
				RectWidth(rcRect),
				RectHeight(rcRect),
				m_rgbBackColor);

	if (m_pImage)
		{
		int x, y;

		//	Compute position of image in the area rect

		if (m_dwStyles & alignCenter)
			x = rcRect.left + (RectWidth(rcRect) - RectWidth(m_rcImage)) / 2;
		else if (m_dwStyles & alignRight)
			x = rcRect.left + (RectWidth(rcRect) - RectWidth(m_rcImage));
		else
			x = rcRect.left;

		if (m_dwStyles & alignMiddle)
			y = rcRect.top + (RectHeight(rcRect) - RectHeight(m_rcImage)) / 2;
		else if (m_dwStyles & alignBottom)
			y = rcRect.top + (RectHeight(rcRect) - RectHeight(m_rcImage));
		else
			y = rcRect.top;

		//	Blt
		//
		//	For compatibility with previous (Transcendence) releases, we assume
		//	black is transparent if the image has no alpha channel.

		CGDraw::BltWithBackColor(Dest,
				x,
				y,
				*m_pImage,
				m_rcImage.left,
				m_rcImage.top,
				RectWidth(m_rcImage),
				RectHeight(m_rcImage),
				CG32bitPixel(0, 0, 0));
		}
	}
Пример #12
0
void CCommandLineDisplay::Paint (CG32bitImage &Dest)

//	Paint
//
//	Paint display

	{
	Update();

	//	Paint the cursor

	m_Buffer.Fill(m_rcCursor.left + 1, 
			m_rcCursor.top, 
			RectWidth(m_rcCursor) - 1, 
			RectHeight(m_rcCursor),
			(((m_iCounter % 30) < 20) ? INPUT_COLOR : BACK_COLOR));

	//	Redraw character under cursor
	if ((m_iCounter % 30) >= 20 && m_iCursorPos < m_sInput.GetLength())
		{
		CString sLine(m_sInput.GetASCIIZPointer() + m_iCursorPos, 1);
		m_Buffer.DrawText(m_rcCursor.left, m_rcCursor.top, m_pFonts->Console, INPUT_COLOR, sLine);
		}

	//	Blt

	Dest.Blt(0,
			0,
			RectWidth(m_rcRect),
			RectHeight(m_rcRect),
			200,
			m_Buffer,
			m_rcRect.left,
			m_rcRect.top);

	m_iCounter++;
	}
Пример #13
0
void CGSelectorArea::PaintModifier (CG32bitImage &Dest, int x, int y, const CString &sText, CG32bitPixel rgbColor, CG32bitPixel rgbBackColor, int *rety)

//	PaintModifier
//
//	Paints a modifier block.

	{
	int cx = m_VI.GetFont(fontSmall).MeasureText(sText);
	if (!rgbBackColor.IsNull())
		Dest.Fill(x - cx - 8,
				y,
				cx + 8,
				m_VI.GetFont(fontSmall).GetHeight(),
				rgbBackColor);

	m_VI.GetFont(fontSmall).DrawText(Dest,
			x - cx - 4,
			y,
			rgbColor,
			sText);

	if (rety)
		*rety = y + m_VI.GetFont(fontSmall).GetHeight() + 1;
	}
Пример #14
0
void CFilterColorizeEntry::GetImage (const CCompositeImageSelector &Selector, CObjectImageArray *retImage)

//	GetImage
//
//	Fills in the image

	{
	//	Null case

	if (m_pSource == NULL)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Get the source image (which we want to colorize)

	CObjectImageArray Source;
	m_pSource->GetImage(Selector, &Source);
	const RECT &rcSource = Source.GetImageRect();
	CG32bitImage &SourceImage = Source.GetImage(NULL_STR);
	int cxWidth = RectWidth(rcSource);
	int cyHeight = RectHeight(rcSource);
	if (!Source.IsLoaded() || cxWidth == 0 || cyHeight == 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Create the destination image

	CG32bitImage *pDest = new CG32bitImage;
	pDest->Create(cxWidth, cyHeight, SourceImage.GetAlphaType());

	//	Blt the to the destination with colorization

	CGDraw::CopyColorize(*pDest,
			0,
			0,
			SourceImage,
			rcSource.left,
			rcSource.top,
			cxWidth,
			cyHeight,
			(REALPIXEL)m_dwHue,
			(REALPIXEL)m_dwSaturation / 100.0);

	//	Initialize an image

	RECT rcFinalRect;
	rcFinalRect.left = 0;
	rcFinalRect.top = 0;
	rcFinalRect.right = cxWidth;
	rcFinalRect.bottom = cyHeight;

	CObjectImageArray Comp;
	Comp.Init(pDest, rcFinalRect, 0, 0, true);

	//	Done

	retImage->TakeHandoff(Comp);
	}
Пример #15
0
void CTranscendenceWnd::CreateNewsAnimation (CMultiverseNewsEntry *pEntry, IAnimatron **retpAnimatron)

//	CreateNewsAnimation
//
//	Creates animation of a Multiverse news entry.

	{
	int iDuration = 600;
	int iInitialFade = 30;
	int iEndFade = 30;

	//	Compute some metrics for the pane based on the entry information

	int cxInnerPane = NEWS_PANE_WIDTH - (2 * NEWS_PANE_PADDING_X);

	CG32bitImage *pImage = pEntry->LoadImageHandoff();
	int cyImage = (pImage ? pImage->GetHeight() : 0);

	TArray<CString> TitleLines;
	m_Fonts.SubTitle.BreakText(pEntry->GetTitle(), cxInnerPane, &TitleLines);
	int cyTitle = m_Fonts.SubTitle.GetHeight() * TitleLines.GetCount();

	TArray<CString> BodyLines;
	m_Fonts.Medium.BreakText(pEntry->GetBody(), cxInnerPane, &BodyLines);
	int cyBody = m_Fonts.Medium.GetHeight() * BodyLines.GetCount();

	TArray<CString> FooterLines;
	m_Fonts.MediumHeavyBold.BreakText(pEntry->GetCallToActionText(), cxInnerPane, &FooterLines);
	int cyFooter = m_Fonts.MediumHeavyBold.GetHeight() * FooterLines.GetCount();

	int cyPane = cyImage
			+ cyTitle
			+ NEWS_PANE_INNER_SPACING_Y
			+ cyBody
			+ NEWS_PANE_INNER_SPACING_Y
			+ cyFooter
			+ NEWS_PANE_PADDING_Y;

	int xPane = m_rcIntroMain.left + (RectWidth(m_rcIntroMain) / 2) + (RectWidth(m_rcIntroMain) / 6);
	int yPane = m_rcIntroMain.top + ((RectHeight(m_rcIntroMain) - cyPane) / 2);

	//	Create sequencer to hold everything The origin of the sequencer is
	//	at the top-center of the pane.

	CAniSequencer *pSeq = new CAniSequencer;
	pSeq->SetPropertyVector(PROP_POSITION, CVector(xPane, yPane));

	int xLeft = -NEWS_PANE_WIDTH / 2;

	//	Create a button that will respond to clicks on the news pane

	CAniButton *pButton = new CAniButton;
	pButton->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0));
	pButton->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane));
	pButton->SetStyle(STYLE_DOWN, NULL);
	pButton->SetStyle(STYLE_HOVER, NULL);
	pButton->SetStyle(STYLE_NORMAL, NULL);
	pButton->SetStyle(STYLE_DISABLED, NULL);
	pButton->SetStyle(STYLE_TEXT, NULL);
	pButton->AddListener(EVENT_ON_CLICK, m_pIntroSession, CMD_OPEN_NEWS);

	pSeq->AddTrack(pButton, 0);

	//	Create the background

	CAniRoundedRect *pPane = new CAniRoundedRect;
	pPane->SetPropertyVector(PROP_POSITION, CVector(xLeft, 0));
	pPane->SetPropertyVector(PROP_SCALE, CVector(NEWS_PANE_WIDTH, cyPane));
	pPane->SetPropertyColor(PROP_COLOR, RGB_NEWS_PANE_BACKGROUND);
	pPane->SetPropertyOpacity(PROP_OPACITY, 64);
	pPane->SetPropertyInteger(PROP_UL_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_UR_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_LL_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->SetPropertyInteger(PROP_LR_RADIUS, NEWS_PANE_CORNER_RADIUS);
	pPane->AnimateLinearFade(iDuration, iInitialFade, iEndFade, 64);

	pSeq->AddTrack(pPane, 0);

	//	Add the content

	int yPos = 0;
	int xInnerLeft = -(cxInnerPane / 2);

	//	Create the image

	if (pImage)
		{
		//	If the image is wide enough to hit the rounded corners, then we
		//	need to mask it out.

		if (pImage->GetWidth() > (NEWS_PANE_WIDTH - 2 * NEWS_PANE_CORNER_RADIUS))
			{
			//	Create a mask the size of the pane and apply it to the image
			//	(We own the image so we can modify it).

			CG8bitImage PaneMask;
			PaneMask.CreateRoundedRect(NEWS_PANE_WIDTH, cyPane, NEWS_PANE_CORNER_RADIUS);
			pImage->IntersectMask(0, 
					0, 
					PaneMask.GetWidth(), 
					PaneMask.GetHeight(), 
					PaneMask,
					(pImage->GetWidth() - PaneMask.GetWidth()) / 2,
					0);
			}

		//	Create an animatron

		CAniRect *pRect = new CAniRect;
		pRect->SetPropertyVector(PROP_POSITION, CVector(-pImage->GetWidth() / 2, yPos));
		pRect->SetPropertyVector(PROP_SCALE, CVector(pImage->GetWidth(), pImage->GetHeight()));
		pRect->SetFillMethod(new CAniImageFill(pImage, true));
		pRect->AnimateLinearFade(iDuration, iInitialFade, iEndFade);

		pSeq->AddTrack(pRect, 0);

		yPos += cyImage;
		}

	//	Create the title

	IAnimatron *pText;
	CAniText::Create(pEntry->GetTitle(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.SubTitle,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	yPos += cyTitle + NEWS_PANE_INNER_SPACING_Y;

	//	Create the text

	CAniText::Create(pEntry->GetBody(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.Medium,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	yPos += cyBody + NEWS_PANE_INNER_SPACING_Y;

	//	Create the call to action

	CAniText::Create(pEntry->GetCallToActionText(),
			CVector(xInnerLeft, yPos),
			&m_Fonts.MediumHeavyBold,
			CG16bitFont::AlignCenter,
			m_Fonts.rgbTitleColor,
			&pText);
	pText->SetPropertyVector(PROP_SCALE, CVector(cxInnerPane, cyPane));
	pText->AnimateLinearFade(iDuration, iInitialFade, iEndFade);
	pSeq->AddTrack(pText, 0);

	//	Remember the URL to open when the user clicks

	m_sNewsURL = pEntry->GetCallToActionURL();

	//	Done

	*retpAnimatron = pSeq;
	}
Пример #16
0
void GenerateImageChart (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	enum OrderTypes
		{
		orderSmallest = 1,
		orderLargest = 2,
		orderName = 3,
		orderLevel = 4,
		orderSovereign = 5,
		orderManufacturer = 6,
		};

	//	Item criteria

	bool bHasItemCriteria;
	CString sCriteria;
	CItemCriteria ItemCriteria;
	if (bHasItemCriteria = pCmdLine->FindAttribute(CONSTLIT("itemCriteria"), &sCriteria))
		CItem::ParseCriteria(sCriteria, &ItemCriteria);
	else
		CItem::InitCriteriaAll(&ItemCriteria);

	//	Get the criteria from the command line.

	CDesignTypeCriteria Criteria;
	if (pCmdLine->FindAttribute(CONSTLIT("criteria"), &sCriteria))
		{
		if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR)
			{
			printf("ERROR: Unable to parse criteria.\n");
			return;
			}
		}
	else if (bHasItemCriteria)
		{
		if (CDesignTypeCriteria::ParseCriteria(CONSTLIT("i"), &Criteria) != NOERROR)
			{
			printf("ERROR: Unable to parse criteria.\n");
			return;
			}
		}
	else
		{
		printf("ERROR: Expected criteria.\n");
		return;
		}

	bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all"));

	//	Options

	bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly"));
	bool bFieldUNID = pCmdLine->GetAttributeBool(CONSTLIT("unid"));

	//	Figure out what order we want

	CString sOrder = pCmdLine->GetAttribute(CONSTLIT("sort"));
	int iOrder;
	if (strEquals(sOrder, CONSTLIT("smallest")))
		iOrder = orderSmallest;
	else if (strEquals(sOrder, CONSTLIT("largest")))
		iOrder = orderLargest;
	else if (strEquals(sOrder, CONSTLIT("level")))
		iOrder = orderLevel;
	else if (strEquals(sOrder, CONSTLIT("sovereign")))
		iOrder = orderSovereign;
	else if (strEquals(sOrder, CONSTLIT("manufacturer")))
		iOrder = orderManufacturer;
	else
		iOrder = orderName;

	bool b3DGrid = pCmdLine->GetAttributeBool(CONSTLIT("3DGrid"));
	bool bDockingPorts = pCmdLine->GetAttributeBool(CONSTLIT("portPos"));
	bool bDevicePos = pCmdLine->GetAttributeBool(CONSTLIT("devicePos"));

	//	Image size

	int cxDesiredWidth;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("width"), &cxDesiredWidth))
		cxDesiredWidth = Max(512, cxDesiredWidth);
	else
		cxDesiredWidth = 1280;

	//	Spacing

	int cxSpacing = pCmdLine->GetAttributeInteger(CONSTLIT("xSpacing"));
	int cxExtraMargin = pCmdLine->GetAttributeInteger(CONSTLIT("xMargin"));
	int cxImageMargin = 2 * pCmdLine->GetAttributeInteger(CONSTLIT("xImageMargin"));

	//	Font for text

	CString sTypeface;
	int iSize;
	bool bBold;
	bool bItalic;

	if (!CG16bitFont::ParseFontDesc(pCmdLine->GetAttribute(CONSTLIT("font")),
			&sTypeface,
			&iSize,
			&bBold,
			&bItalic))
		{
		sTypeface = CONSTLIT("Arial");
		iSize = 10;
		bBold = false;
		bItalic = false;
		}

	CG16bitFont NameFont;
	NameFont.Create(sTypeface, -PointsToPixels(iSize), bBold, bItalic);
	CG32bitPixel rgbNameColor = CG32bitPixel(255, 255, 255);

	//	Rotation

	int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation"));

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

	//	Generate a sorted table of types

	TSortMap<CString, SEntryDesc> Table;
	for (i = 0; i < Universe.GetDesignTypeCount(); i++)
		{
		CDesignType *pType = Universe.GetDesignType(i);
		SEntryDesc NewEntry;

		//	Make sure we match the criteria

		if (!pType->MatchesCriteria(Criteria))
			continue;

		//	Figure stuff stuff out based on the specific design type

		switch (pType->GetType())
			{
			case designItemType:
				{
				CItemType *pItemType = CItemType::AsType(pType);
				CItem Item(pItemType, 1);

				//	Skip if not in item criteria

				if (!Item.MatchesCriteria(ItemCriteria))
					continue;

				//	Skip virtual classes

				if (pItemType->IsVirtual())
					continue;

				//	Initialize the entry

				NewEntry.pType = pType;
				NewEntry.sName = pItemType->GetNounPhrase(0);
				NewEntry.pImage = &pItemType->GetImage();
				NewEntry.iSize = RectWidth(NewEntry.pImage->GetImageRect());
				break;
				}

			case designShipClass:
				{
				CShipClass *pClass = CShipClass::AsType(pType);

				//	Skip non-generic classess

				if (!bAll && !pClass->HasLiteralAttribute(CONSTLIT("genericClass")))
					continue;

				//	Initialize the entry

				NewEntry.pType = pType;
				NewEntry.sName = pClass->GetNounPhrase(0);
				NewEntry.iSize = RectWidth(pClass->GetImage().GetImageRect());
				NewEntry.pImage = &pClass->GetImage();
				NewEntry.iRotation = pClass->Angle2Direction(iRotation);
				NewEntry.sSovereignName = (pClass->GetDefaultSovereign() ? pClass->GetDefaultSovereign()->GetTypeNounPhrase() : NULL_STR);
				break;
				}

			case designStationType:
				{
				CStationType *pStationType = CStationType::AsType(pType);

				//	Skip generic classes

				if (!bAll && !pStationType->HasLiteralAttribute(CONSTLIT("generic")))
					continue;

				NewEntry.pType = pType;
				NewEntry.sName = pStationType->GetNounPhrase(0);
				NewEntry.iSize = pStationType->GetSize();
				NewEntry.sSovereignName = (pStationType->GetSovereign() ? pStationType->GetSovereign()->GetTypeNounPhrase() : NULL_STR);

				InitStationTypeImage(NewEntry, pStationType);

				break;
				}

			default:
				//	Don't know how to handle this type
				continue;
				break;
			}

		//	Adjust name

		if (bFieldUNID)
			NewEntry.sName = strPatternSubst(CONSTLIT("%s (%x)"), NewEntry.sName, NewEntry.pType->GetUNID());

		//	Compute the sort key

		char szBuffer[1024];
		switch (iOrder)
			{
			case orderLargest:
				wsprintf(szBuffer, "%09d%s%x",
						1000000 - NewEntry.iSize,
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderLevel:
				wsprintf(szBuffer, "%09d%s%x",
						pType->GetLevel(),
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderSmallest:
				wsprintf(szBuffer, "%09d%s%x",
						NewEntry.iSize,
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderSovereign:
				wsprintf(szBuffer, "%s|%s|%x", NewEntry.sSovereignName.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				NewEntry.sCategorize = NewEntry.sSovereignName;
				break;

			case orderManufacturer:
				{
				CString sManufacturer = NewEntry.pType->GetPropertyString(CONSTLIT("manufacturer"));
				wsprintf(szBuffer, "%s|%s|%x", sManufacturer.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				NewEntry.sCategorize = sManufacturer;
				break;
				}

			default:
				wsprintf(szBuffer, "%s%x", NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				break;
			}

		//	Add to list

		Table.Insert(CString(szBuffer), NewEntry);
		}

	//	Allocate an arranger that tracks where to paint each world.

	CImageArranger Arranger;

	//	Settings for the overall arrangement

	CImageArranger::SArrangeDesc Desc;
	Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin)));
	Desc.cxSpacing = cxSpacing;
	Desc.cxExtraMargin = cxExtraMargin;
	Desc.pHeader = &NameFont;

	//	Generate a table of cells for the arranger

	TArray<CCompositeImageSelector> Selectors;
	Selectors.InsertEmpty(Table.GetCount());

	CString sLastCategory;
	TArray<CImageArranger::SCellDesc> Cells;
	for (i = 0; i < Table.GetCount(); i++)
		{
		SEntryDesc &Entry = Table[i];

		CImageArranger::SCellDesc *pNewCell = Cells.Insert();
		pNewCell->cxWidth = (Entry.pImage ? RectWidth(Entry.pImage->GetImageRect()) : 0) + cxImageMargin;
		pNewCell->cyHeight = (Entry.pImage ? RectHeight(Entry.pImage->GetImageRect()) : 0) + cxImageMargin;
		pNewCell->sText = Entry.sName;

		if (!strEquals(sLastCategory, Entry.sCategorize))
			{
			sLastCategory = Entry.sCategorize;
			pNewCell->bStartNewRow = true;
			}
		}

	//	Arrange

	Arranger.ArrangeByRow(Desc, Cells);

	//	Create a large image

	CG32bitImage Output;
	int cxWidth = Max(cxDesiredWidth, Arranger.GetWidth());
	int cyHeight = Arranger.GetHeight();
	Output.Create(cxWidth, cyHeight);
	printf("Creating %dx%d image.\n", cxWidth, cyHeight);

	//	Paint the images

	for (i = 0; i < Table.GetCount(); i++)
		{
		SEntryDesc &Entry = Table[i];

		int x = Arranger.GetX(i);
		int y = Arranger.GetY(i);

		//	Paint

		if (x != -1)
			{
			int xCenter = x + (Arranger.GetWidth(i) / 2);
			int yCenter = y + (Arranger.GetHeight(i) / 2);

			int xOffset;
			int yOffset;
			Entry.pImage->GetImageOffset(0, Entry.iRotation, &xOffset, &yOffset);
			int cxImage = RectWidth(Entry.pImage->GetImageRect());
			int cyImage = RectHeight(Entry.pImage->GetImageRect());

			//	Paint image

			if (!bTextBoxesOnly && Entry.pImage)
				{
				Entry.pImage->PaintImageUL(Output,
						x + (Arranger.GetWidth(i) - cxImage) / 2,
						y + (Arranger.GetHeight(i) - cyImage) / 2,
						0,
						Entry.iRotation);
				}

			//	Paint type specific stuff

			switch (Entry.pType->GetType())
				{
				case designStationType:
					{
					CStationType *pStationType = CStationType::AsType(Entry.pType);
                    int xStationCenter = xCenter - xOffset;
                    int yStationCenter = yCenter - yOffset;

					if (bDockingPorts)
						pStationType->PaintDockPortPositions(Output, xStationCenter, yStationCenter);

					if (bDevicePos)
						pStationType->PaintDevicePositions(Output, xStationCenter, yStationCenter);

                    //  If we have docking or device positions, mark the center of the station

                    if (bDockingPorts || bDevicePos)
                        {
                        const int LINE_HALF_LENGTH = 24;
                        const CG32bitPixel RGB_CENTER_CROSS(255, 255, 0);
                        Output.DrawLine(xStationCenter - LINE_HALF_LENGTH, yStationCenter, xStationCenter + LINE_HALF_LENGTH, yStationCenter, 1, RGB_CENTER_CROSS);
                        Output.DrawLine(xStationCenter, yStationCenter - LINE_HALF_LENGTH, xStationCenter, yStationCenter + LINE_HALF_LENGTH, 1, RGB_CENTER_CROSS);
                        }
					break;
					}
				}

			//	Paint the 3D grid, if necessary

			if (b3DGrid)
				{
				int iScale = Entry.pImage->GetImageViewportSize();
				Metric rMaxRadius = g_KlicksPerPixel * cxImage * 0.5;
				const Metric rGridSize = LIGHT_SECOND;

				Metric rRadius;
				for (rRadius = rGridSize; rRadius <= rMaxRadius; rRadius += rGridSize)
					{
					int iRadius = (int)((rRadius / g_KlicksPerPixel) + 0.5);
					const int iGridAngle = 8;
					int iPrevAngle = 0;
					int iAngle;
					for (iAngle = iGridAngle; iAngle <= 360; iAngle += iGridAngle)
						{
						int xFrom, yFrom;
						C3DConversion::CalcCoord(iScale, iPrevAngle, iRadius, 0, &xFrom, &yFrom);

						int xTo, yTo;
						C3DConversion::CalcCoord(iScale, iAngle, iRadius, 0, &xTo, &yTo);

						Output.DrawLine(xFrom + xCenter, yFrom + yCenter, xTo + xCenter, yTo + yCenter, 1, CG32bitPixel(255, 255, 0));

						iPrevAngle = iAngle;
						}
					}
				}

			//	Paint name

			int xText = Arranger.GetTextX(i);
			int yText = Arranger.GetTextY(i);
			if (xText != -1)
				{
				if (bTextBoxesOnly)
					Output.Fill(xText, yText, Arranger.GetTextWidth(i), Arranger.GetTextHeight(i), 0xffff);

				if (!bTextBoxesOnly)
					{
					Output.FillColumn(xCenter,
							y + Arranger.GetHeight(i),
							yText - (y + Arranger.GetHeight(i)),
							rgbNameColor);

					NameFont.DrawText(Output,
							xText,
							yText,
							rgbNameColor,
							Entry.sName);
					}
				}
			}
		}

	//	Write to file or clipboard

	OutputImage(Output, sFilespec);
	}
Пример #17
0
void GenerateSnapshot (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	ALERROR error;
	int i;

	//	Get some parameters

	int iInitialUpdateTime = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("initialUpdate"), 0, -1, 10);
	int iUpdateTime = pCmdLine->GetAttributeInteger(CONSTLIT("wait"));
	bool bObjOnly = pCmdLine->GetAttributeBool(CONSTLIT("objOnly"));

	//	Criteria

	CString sNode = pCmdLine->GetAttribute(CONSTLIT("node"));
	CString sCriteria = pCmdLine->GetAttribute(CONSTLIT("criteria"));

	//	Number of snapshots

	int iTotalCount = pCmdLine->GetAttributeIntegerBounded(CONSTLIT("count"), 1, -1, 1);

	//	Output

	int cxWidth;
	int cyHeight;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("size"), &cxWidth))
		{
		cyHeight = cxWidth;
		}
	else
		{
		cxWidth = 1024;
		cyHeight = 1024;
		}

	//	Paint flags

	DWORD dwPaintFlags = 0;
	if (pCmdLine->GetAttributeBool(CONSTLIT("noStars")))
		dwPaintFlags |= CSystem::VWP_NO_STAR_FIELD;

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathStripExtension(sFilespec);

	//	Output image

	CG32bitImage Output;
	Output.Create(cxWidth, cyHeight);

	//	Update context

	SSystemUpdateCtx Ctx;
	Ctx.bForceEventFiring = true;
	Ctx.bForcePainted = true;

	RECT rcViewport;
	rcViewport.left = 0;
	rcViewport.top = 0;
	rcViewport.right = cxWidth;
	rcViewport.bottom = cyHeight;

	//	Loop over all systems until we find what we're looking for

	int iLoops = 20;
	int iNodeIndex = 0;
	int iSnapshotIndex = 0;
	CTopologyNode *pNode = Universe.GetTopologyNode(iNodeIndex);
	while (true)
		{
		//	Create the system

		CSystem *pSystem;
		if (error = Universe.CreateStarSystem(pNode, &pSystem))
			{
			printf("ERROR: Unable to create star system.\n");
			return;
			}

		//	If this is the node we want, then search

		CSpaceObject *pTarget;
		if (sNode.IsBlank() || strEquals(sNode, pNode->GetID()))
			{
			printf("Searching %s...\n", pNode->GetSystemName().GetASCIIZPointer());

			//	Set the POV

			CSpaceObject *pPOV = pSystem->GetObject(0);
			Universe.SetPOV(pPOV);
			pSystem->SetPOVLRS(pPOV);

			//	Prepare system

			Universe.UpdateExtended();
			Universe.GarbageCollectLibraryBitmaps();

			//	Update for a while

			for (i = 0; i < iInitialUpdateTime; i++)
				{
				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Compose the criteria

			CSpaceObject::Criteria Criteria;
			CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

			//	Get the list of all objects in the system that match the criteria

			CSpaceObject::SCriteriaMatchCtx Ctx(Criteria);
			TArray<CSpaceObject *> Results;
			for (i = 0; i < pSystem->GetObjectCount(); i++)
				{
				CSpaceObject *pObj = pSystem->GetObject(i);
				if (pObj && pObj->MatchesCriteria(Ctx, Criteria))
					Results.Insert(pObj);
				}

			//	Pick the appropriate object from the list

			if (Results.GetCount() == 0)
				pTarget = NULL;
			else if (Criteria.bNearestOnly || Criteria.bFarthestOnly)
				pTarget = Ctx.pBestObj;
			else
				pTarget = Results[mathRandom(0, Results.GetCount() - 1)];
			}
		else
			pTarget = NULL;

		//	If we found the target, then output

		if (pTarget)
			{
			Universe.SetPOV(pTarget);

			//	Wait a bit
			//
			//	NOTE: After we update, pTarget could be invalid (i.e., destroyed)
			//	so we can't use it again.

			CString sTargetName = pTarget->GetNounPhrase(0);

			for (i = 0; i < iUpdateTime; i++)
				{
				if ((i % 100) == 99)
					printf(".");

				Universe.Update(Ctx);
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			if (iUpdateTime >= 99)
				printf("\n");

			//	Paint

			if (bObjOnly)
				{
				SViewportPaintCtx Ctx;
				Ctx.pObj = Universe.GetPOV();
				Ctx.XForm = ViewportTransform(Universe.GetPOV()->GetPos(), 
						g_KlicksPerPixel, 
						cxWidth / 2, 
						cyHeight / 2);
				Ctx.XFormRel = Ctx.XForm;
				Ctx.fNoRecon = true;
				Ctx.fNoDockedShips = true;
				Ctx.fNoSelection = true;
				Ctx.fNoStarfield = true;

				CSpaceObject *pPOV = pSystem->GetObject(0);
				CSpaceObject::Criteria Criteria;
				CSpaceObject::ParseCriteria(pPOV, sCriteria, &Criteria);

				//	Paint all objects that match the criteria

				CSpaceObject::SCriteriaMatchCtx CriteriaCtx(Criteria);
				for (i = 0; i < pSystem->GetObjectCount(); i++)
					{
					CSpaceObject *pObj = pSystem->GetObject(i);
					if (pObj && pObj->MatchesCriteria(CriteriaCtx, Criteria))
						{
						Ctx.pObj = pObj;
						int xObj;
						int yObj;
						Ctx.XForm.Transform(pObj->GetPos(), &xObj, &yObj);

						pObj->Paint(Output, xObj, yObj, Ctx);
						}
					}
				}
			else
				{
			
				Universe.PaintPOV(Output, rcViewport, 0);
				}

			//	Write to file

			if (!sFilespec.IsBlank())
				{
				CString sBmpFilespec;
				if (iTotalCount > 100)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%03d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else if (iTotalCount > 1)
					sBmpFilespec = pathAddExtensionIfNecessary(strPatternSubst(CONSTLIT("%s%02d"), sFilespec, iSnapshotIndex + 1), CONSTLIT(".bmp"));
				else
					sBmpFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

				CFileWriteStream OutputFile(sBmpFilespec);
				if (OutputFile.Create() != NOERROR)
					{
					printf("ERROR: Unable to create '%s'\n", sBmpFilespec.GetASCIIZPointer());
					return;
					}

				Output.WriteToWindowsBMP(&OutputFile);
				OutputFile.Close();
				printf("Found %s: Saved to %s\n", sTargetName.GetASCIIZPointer(), sBmpFilespec.GetASCIIZPointer());
				}

			//	Otherwise, clipboard

			else
				{
				if (error = Output.CopyToClipboard())
					{
					printf("ERROR: Unable to copy image to clipboard.\n");
					return;
					}

				printf("Found %s: Copied to clipboard.\n", sTargetName.GetASCIIZPointer());
				}

			//	Reset maximum loops

			iLoops = 20;

			//	Done

			iSnapshotIndex++;
			if (iSnapshotIndex >= iTotalCount)
				break;
			}

		//	Done with old system

		Universe.DestroySystem(pSystem);

		//	Loop to the next node

		do
			{
			iNodeIndex = ((iNodeIndex + 1) % Universe.GetTopologyNodeCount());
			pNode = Universe.GetTopologyNode(iNodeIndex);
			}
		while (pNode == NULL || pNode->IsEndGame());

		//	If we're back to the first node again, restart

		if (iNodeIndex == 0)
			{
			if (--iLoops > 0)
				{
				//	Reinitialize

				Universe.Reinit();
				CString sError;
				if (Universe.InitGame(0, &sError) != NOERROR)
					{
					printf("ERROR: %s\n", sError.GetASCIIZPointer());
					return;
					}

				iNodeIndex = 0;
				pNode = Universe.GetTopologyNode(iNodeIndex);
				}
			else
				{
				printf("ERROR: Specified target could not be found.\n");
				return;
				}
			}
		}
	}
Пример #18
0
void CNewGameSession::SetShipClassImage (CShipClass *pClass, int x, int y, int cxWidth)

//	SetShipClassImage
//
//	Sets the current ship class image

	{
	const CPlayerSettings *pPlayerSettings = pClass->GetPlayerSettings();

    //  Ask the class for a hero image

    const CG32bitImage *pImage = (!pClass->GetHeroImage().IsEmpty() ? &pClass->GetHeroImage().GetImage(CONSTLIT("New Game")) : NULL);
    
	//	Delete the previous one

	DeleteElement(ID_SHIP_CLASS_IMAGE);

	//	Add the new one, if we've got one.

	const CG32bitImage *pImageToUse = NULL;
	bool bFree = false;

	if (pImage && !pImage->IsEmpty())
		{
		//	If this image is not the right size, then create a resized version
		//	that is.

		if (pImage->GetWidth() != SHIP_IMAGE_WIDTH || pImage->GetHeight() != SHIP_IMAGE_HEIGHT)
			{
			int cxNewWidth = SHIP_IMAGE_WIDTH;
			int cyNewHeight = cxNewWidth * pImage->GetHeight() / pImage->GetWidth();
			if (cyNewHeight > SHIP_IMAGE_HEIGHT)
				{
				cyNewHeight = SHIP_IMAGE_HEIGHT;
				cxNewWidth = cyNewHeight * pImage->GetWidth() / pImage->GetHeight();
				}

			CG32bitImage *pNewImage = new CG32bitImage;
			pNewImage->CreateFromImageTransformed(*pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight(), (Metric)cxNewWidth / pImage->GetWidth(), (Metric)cyNewHeight / pImage->GetHeight(), 0.0);

			pImageToUse = pNewImage;
			bFree = true;
			}
		else
			{
			pImageToUse = pImage;
			bFree = false;
			}
		}

	//	If we don't have an image then ask the class to paint it

	else
		{
		CG32bitImage *pNewImage = new CG32bitImage;
		pNewImage->Create(SHIP_IMAGE_WIDTH, SHIP_IMAGE_HEIGHT);

		ViewportTransform Trans;
		pClass->Paint(*pNewImage, 
				SHIP_IMAGE_WIDTH / 2, 
				SHIP_IMAGE_HEIGHT / 2, 
				Trans, 
				0, 
				0
				);

		pImageToUse = pNewImage;
		bFree = true;
		}

	//	Position

	int xImage = x + (cxWidth - pImageToUse->GetWidth()) / 2;
	int yImage = y + (SHIP_IMAGE_HEIGHT - pImageToUse->GetHeight()) / 2;

	//	New image frame

	bool bAutoMask = (pClass->GetAPIVersion() < 26);

	IAnimatron *pImageFrame = new CAniRect;
	pImageFrame->SetID(ID_SHIP_CLASS_IMAGE);
	pImageFrame->SetPropertyVector(PROP_POSITION, CVector(xImage, yImage));
	pImageFrame->SetPropertyVector(PROP_SCALE, CVector(pImageToUse->GetWidth(), pImageToUse->GetHeight()));
	pImageFrame->SetFillMethod(new CAniImageFill(pImageToUse, bFree, bAutoMask));

	m_pRoot->AddLine(pImageFrame);
	}
Пример #19
0
void InitStationTypeImage (SEntryDesc &Entry, CStationType *pStationType)
	{
	struct SSatImageDesc
		{
		const CObjectImageArray *pImage;
		CCompositeImageSelector Selector;
		int xOffset;
		int yOffset;
		};

	int i;

	SSelectorInitCtx InitCtx;
	pStationType->SetImageSelector(InitCtx, &Entry.Selector);
	const CObjectImageArray *pMainImage = &pStationType->GetImage(Entry.Selector, CCompositeImageModifiers());

	//	If we have no satellites, then we can just return the single station 
	//	image.

	CXMLElement *pSatellites = pStationType->GetSatellitesDesc();
	if (pSatellites == NULL)
		{
		Entry.pImage = pMainImage;
		return;
		}

	//	Figure out the extents of the image

	RECT rcMainImage = pMainImage->GetImageRect();
	RECT rcBounds;
	rcBounds.left = -(RectWidth(rcMainImage) / 2);
	rcBounds.top = -(RectHeight(rcMainImage) / 2);
	rcBounds.right = rcBounds.left + RectWidth(rcMainImage);
	rcBounds.bottom = rcBounds.top + RectHeight(rcMainImage);

	//	Loop over all satellites and get metrics

	TArray<SSatImageDesc> SatImages;
	for (i = 0; i < pSatellites->GetContentElementCount(); i++)
		{
		CXMLElement *pSatDesc = pSatellites->GetContentElement(i);
		if (!pSatDesc->FindAttribute(SEGMENT_ATTRIB)
				|| !strEquals(STATION_TAG, pSatDesc->GetTag()))
			continue;

		//	Get the type of the satellite

		CStationType *pSatType = g_pUniverse->FindStationType(pSatDesc->GetAttributeInteger(TYPE_ATTRIB));
		if (pSatType == NULL)
			continue;

		//	Prepare the image for the satellite

		SSatImageDesc *pSatImage = SatImages.Insert();
		pSatType->SetImageSelector(InitCtx, &pSatImage->Selector);

		//	If we have an image variant, then set it

		int iVariant;
		if (pSatDesc->FindAttributeInteger(IMAGE_VARIANT_ATTRIB, &iVariant))
			{
			IImageEntry *pRoot = pSatType->GetImage().GetRoot();
			DWORD dwID = (pRoot ? pRoot->GetID() : DEFAULT_SELECTOR_ID);

			pSatImage->Selector.DeleteAll();
			pSatImage->Selector.AddVariant(dwID, iVariant);
			}

		pSatImage->pImage = &pSatType->GetImage(pSatImage->Selector, CCompositeImageModifiers());

		//	Now get the offset

		pSatImage->xOffset = pSatDesc->GetAttributeInteger(X_OFFSET_ATTRIB);
		pSatImage->yOffset = pSatDesc->GetAttributeInteger(Y_OFFSET_ATTRIB);

		//	Compute the satellite rect

		RECT rcSatImage = pSatImage->pImage->GetImageRect();
		RECT rcSatBounds;
		rcSatBounds.left = pSatImage->xOffset - (RectWidth(rcSatImage) / 2);
		rcSatBounds.top = -pSatImage->yOffset - (RectHeight(rcSatImage) / 2);
		rcSatBounds.right = rcSatBounds.left + RectWidth(rcSatImage);
		rcSatBounds.bottom = rcSatBounds.top + RectHeight(rcSatImage);

		//	Increase the size of the bounds

		rcBounds.left = Min(rcBounds.left, rcSatBounds.left);
		rcBounds.right = Max(rcBounds.right, rcSatBounds.right);
		rcBounds.top = Min(rcBounds.top, rcSatBounds.top);
		rcBounds.bottom = Max(rcBounds.bottom, rcSatBounds.bottom);
		}

	//	If no segments, then we just return the basic image

	if (SatImages.GetCount() == 0)
		{
		Entry.pImage = pMainImage;
		return;
		}

	//	Create an image that will hold the composite

	CG32bitImage *pCompositeImage = new CG32bitImage;
	pCompositeImage->Create(RectWidth(rcBounds), RectHeight(rcBounds), CG32bitImage::alpha8, CG32bitPixel::Null());
	int xCenter = -rcBounds.left;
	int yCenter = -rcBounds.top;

	//	Paint the main image

	pMainImage->PaintImage(*pCompositeImage, xCenter, yCenter, 0, Entry.iRotation, true);

	//	Paint all the satellites

	for (i = 0; i < SatImages.GetCount(); i++)
		SatImages[i].pImage->PaintImage(*pCompositeImage, xCenter + SatImages[i].xOffset, yCenter - SatImages[i].yOffset, 0, 0, true);

	//	Now create the proper image array

	RECT rcResult;
	rcResult.left = 0;
	rcResult.top = 0;
	rcResult.right = RectWidth(rcBounds);
	rcResult.bottom = RectHeight(rcBounds);

    int xOffset = (RectWidth(rcBounds) / 2) - xCenter;
    int yOffset = (RectHeight(rcBounds) / 2) - yCenter;

	Entry.pCompositeImageArray = new CObjectImageArray;
	Entry.pCompositeImageArray->Init(pCompositeImage, rcResult, 0, 0, true, xOffset, yOffset);

	//	Done

	Entry.pImage = Entry.pCompositeImageArray;
	}
Пример #20
0
void CButtonBarDisplay::Paint (CG32bitImage &Dest)

//	Paint
//
//	Paint the bar

	{
	int i;

	//	Fill background

	Dest.Fill(m_rcRect.left,
			m_rcRect.top,
			RectWidth(m_rcRect),
			RectHeight(m_rcRect),
			BAR_COLOR);

	//	Get the images

	const CG32bitImage &Images = m_pButtons->GetImage();

	//	Paint each button

	for (i = 0; i < m_pButtons->GetCount(); i++)
		{
		RECT rcRect = m_pButtons->GetButtonRect(i);

		//	Skip invisible buttons

		if (!m_pButtons->GetVisible(i))
			continue;

		//	Paint the image

		RECT rcSrc;
		GetImageRect(i, (i == m_iSelected), &rcSrc);

		Dest.Blt(rcSrc.left,
				rcSrc.top,
				RectWidth(rcSrc),
				RectHeight(rcSrc),
				Images,
				rcRect.left,
				rcRect.top);

		//	Paint the button label

		int cxWidth = m_pFonts->SubTitle.MeasureText(m_pButtons->GetLabel(i), NULL);
		m_pFonts->SubTitle.DrawText(Dest,
				rcRect.left + (RectWidth(rcRect) - cxWidth) / 2,
				rcRect.top + BUTTON_LABEL_Y,
				CG32bitPixel(128,128,128),
				m_pButtons->GetLabel(i));

		//	Paint the description

		cxWidth = m_pFonts->Medium.MeasureText(m_pButtons->GetDescription(i), NULL);
		m_pFonts->Medium.DrawText(Dest,
				rcRect.left + (RectWidth(rcRect) - cxWidth) / 2,
				rcRect.top + BUTTON_DESCRIPTION_Y,
				CG32bitPixel(255,255,255),
				m_pButtons->GetDescription(i));
		}
	}
Пример #21
0
void CExtensionNavigator::DrawTitleBar(CG32bitImage &Screen)
	{
	Screen.DrawText(m_AssociatedPanel.GetOriginX() + 10, m_AssociatedPanel.GetOriginY() + 10, m_HeadingFont, m_HeadingColor, CONSTLIT("Extension Navigator"));
	}
Пример #22
0
void CG8bitSparseImage::MaskFill (CG32bitImage &Dest, int xDest, int yDest, int cxDest, int cyDest, int xSrc, int ySrc, CG32bitPixel rgbColor) const

//	MaskFill
//
//	Fills the destination image with the given color through our mask.

	{
	//	Make sure we're in bounds

	if (!Dest.AdjustCoords(&xSrc, &ySrc, GetWidth(), GetHeight(), 
			&xDest, &yDest,
			&cxDest, &cyDest))
		return;

	//	Short-circuit

	if (rgbColor.GetAlpha() == 0x00)
		return;

	//	Compute a pre-multiplied color

	BYTE *pAlpha = CG32bitPixel::AlphaTable(rgbColor.GetAlpha());
	CG32bitPixel rgbPreMultColor = CG32bitPixel(pAlpha[rgbColor.GetRed()], pAlpha[rgbColor.GetGreen()], pAlpha[rgbColor.GetBlue()], rgbColor.GetAlpha());

	//	Loop

	int yPos = ySrc;
	int yPosEnd = ySrc + cyDest;
	int yTile = yPos / m_cyTile;
	int yOffset = ClockMod(yPos, m_cyTile);
	int xTileStart = xSrc / m_cxTile;
	int xOffsetStart = ClockMod(xSrc, m_cxTile);

	int yDestPos = yDest;
	while (yPos < yPosEnd)
		{
		int cyTileLeft = Min(m_cyTile - yOffset, yPosEnd - yPos);

		//	Is this a valid tile row, then continue

		if (yTile >= 0 && yTile < m_yTileCount)
			{
			int xPos = xSrc;
			int xPosEnd = xSrc + cxDest;
			int xTile = xTileStart;
			int xOffset = xOffsetStart;

			int xDestPos = xDest;
			while (xPos < xPosEnd)
				{
				int cxTileLeft = Min(m_cxTile - xOffset, xPosEnd - xPos);

				//	If this is a valid tile, then we can continue

				if (xTile >= 0 && xTile < m_xTileCount)
					{
					const CNode &Tile = GetTile(xTile, yTile);

					switch (Tile.GetType())
						{
						case typeByte:
							{
							BYTE byAlpha = Tile.GetByte();
							if (byAlpha == 0x00)
								{}
							else if (byAlpha == 0xff)
								Dest.Fill(xDestPos, yDestPos, cxTileLeft, cyTileLeft, rgbColor);
							else
								//	We just modify the alpha on the original color (Fill will take care of the rest)
								Dest.Fill(xDestPos, yDestPos, cxTileLeft, cyTileLeft, CG32bitPixel(rgbColor, CG32bitPixel::BlendAlpha(rgbColor.GetAlpha(), byAlpha)));
							break;
							}

						case typeNodeArray:
							{
							CNode *Rows = Tile.GetNodeArray();
							CNode *pSrcRow = Rows + yOffset;
							CNode *pSrcRowEnd = pSrcRow + cyTileLeft;

							CG32bitPixel *pDestRow = Dest.GetPixelPos(xDestPos, yDestPos);

							while (pSrcRow < pSrcRowEnd)
								{
								CG32bitPixel *pDest = pDestRow;
								CG32bitPixel *pDestEnd = pDestRow + cxTileLeft;

								switch (pSrcRow->GetType())
									{
									case typeByte:
										{
										BYTE byAlpha = pSrcRow->GetByte();
										if (byAlpha == 0x00)
											{}
										else if (byAlpha == 0xff)
											{
											BYTE byFillAlpha = rgbColor.GetAlpha();
											if (byFillAlpha == 0xff)
												{
												while (pDest < pDestEnd)
													*pDest++ = rgbColor;
												}
											else
												{
												BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

												BYTE byRed = rgbPreMultColor.GetRed();
												BYTE byGreen = rgbPreMultColor.GetGreen();
												BYTE byBlue = rgbPreMultColor.GetBlue();

												while (pDest < pDestEnd)
													{
													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + byRed;
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + byGreen;
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + byBlue;

													*pDest++ = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}
												}
											}
										else
											{
											//	Blend the alphas together
											BYTE byFillAlpha = CG32bitPixel::BlendAlpha(byAlpha, rgbColor.GetAlpha());

											BYTE *pAlpha = CG32bitPixel::AlphaTable(byFillAlpha);
											BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

											BYTE byRed = pAlpha[rgbColor.GetRed()];
											BYTE byGreen = pAlpha[rgbColor.GetBlue()];
											BYTE byBlue = pAlpha[rgbColor.GetGreen()];

											while (pDest < pDestEnd)
												{
												BYTE byRedResult = pAlphaInv[pDest->GetRed()] + byRed;
												BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + byGreen;
												BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + byBlue;

												*pDest++ = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
												}
											}
										break;
										}

									case typeByteArray:
										{
										BYTE *pSrcAlpha = pSrcRow->GetByteArray() + xOffset;
										BYTE *pSrcAlphaEnd = pSrcAlpha + cxTileLeft;

										BYTE byColorAlpha = rgbColor.GetAlpha();
										if (byColorAlpha == 0xff)
											{
											while (pSrcAlpha < pSrcAlphaEnd)
												{
												if (*pSrcAlpha == 0x00)
													{}
												else if (*pSrcAlpha == 0xff)
													*pDest = rgbColor;
												else
													{
													BYTE *pAlpha = CG32bitPixel::AlphaTable(*pSrcAlpha);
													BYTE *pAlphaInv = CG32bitPixel::AlphaTable(*pSrcAlpha ^ 0xff);

													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + pAlpha[rgbColor.GetRed()];
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + pAlpha[rgbColor.GetGreen()];
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + pAlpha[rgbColor.GetBlue()];

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}

												pSrcAlpha++;
												pDest++;
												}
											}
										else
											{
											BYTE *pAlphaFFInv = CG32bitPixel::AlphaTable(byColorAlpha ^ 0xff);

											while (pSrcAlpha < pSrcAlphaEnd)
												{
												if (*pSrcAlpha == 0x00)
													{}
												else if (*pSrcAlpha == 0xff)
													{
													BYTE byRedResult = pAlphaFFInv[pDest->GetRed()] + rgbPreMultColor.GetRed();
													BYTE byGreenResult = pAlphaFFInv[pDest->GetGreen()] + rgbPreMultColor.GetGreen();
													BYTE byBlueResult = pAlphaFFInv[pDest->GetBlue()] + rgbPreMultColor.GetBlue();

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}
												else
													{
													BYTE byFillAlpha = CG32bitPixel::BlendAlpha(*pSrcAlpha, byColorAlpha);

													BYTE *pAlpha = CG32bitPixel::AlphaTable(byFillAlpha);
													BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + pAlpha[rgbColor.GetRed()];
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + pAlpha[rgbColor.GetGreen()];
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + pAlpha[rgbColor.GetBlue()];

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}

												pSrcAlpha++;
												pDest++;
												}
											}
										break;
										}
									}

								pSrcRow++;
								pDestRow = Dest.NextRow(pDestRow);
								}

							break;
							}
						}
					}

				//	Move to the next tile

				xTile++;
				xOffset = 0;
				xPos += cxTileLeft;
				xDestPos += cxTileLeft;
				}
			}

		//	Next tile row

		yTile++;
		yOffset = 0;
		yPos += cyTileLeft;
		yDestPos += cyTileLeft;
		}
	}
Пример #23
0
void CGItemListArea::Paint (CG32bitImage &Dest, const RECT &rcRect)

//	Paint
//
//	Paint the area

	{
	//	Can't paint if we are not properly initialized

	if (m_pFonts == NULL)
		return;

	bool bPaintCursor = false;
	RECT rcCursor;

	//	Paint Background

    CG32bitPixel rgbFadeBackColor = CG32bitPixel(CG32bitPixel::Darken(m_rgbBackColor, 220), 220);
	CGDraw::RoundedRect(Dest,
			rcRect.left,
			rcRect.top,
			RectWidth(rcRect),
			RectHeight(rcRect),
			BORDER_RADIUS + 1,
			rgbFadeBackColor);

	//	If there are no items here, then say so

	if (m_pListData == NULL || !m_pListData->IsCursorValid())
		{
		int x = rcRect.left + (RectWidth(rcRect) - m_pFonts->LargeBold.MeasureText(STR_NO_ITEMS)) / 2;
		int y = rcRect.top + (RectHeight(rcRect) - m_pFonts->LargeBold.GetHeight()) / 2;

		Dest.DrawText(x, y,
				m_pFonts->LargeBold,
				RGB_DISABLED_TEXT,
				STR_NO_ITEMS);

		m_iOldCursor = -1;
		}

	//	Otherwise, paint the list of items

	else
		{
		int iCursor = m_pListData->GetCursor();
		int iCount = m_pListData->GetCount();

		ASSERT(iCursor >= 0 && iCursor < m_Rows.GetCount());

		//	If the cursor has changed, update the offset so that we
		//	have a smooth scroll.

		if (m_iOldCursor != -1 
				&& m_iOldCursor != iCursor
				&& m_iOldCursor < m_Rows.GetCount())
			{
			int cyDiff = (m_Rows[iCursor].cyHeight - m_Rows[m_iOldCursor].cyHeight) / 2;

			if (m_iOldCursor < iCursor)
				m_yOffset = m_Rows[m_iOldCursor].cyHeight + cyDiff;
			else
				m_yOffset = -(m_Rows[iCursor].cyHeight - cyDiff);
			}

		m_iOldCursor = iCursor;

		//	Figure out the ideal position of the cursor (relative to the
		//	rect).

		int yIdeal = m_yOffset + ((RectHeight(rcRect) - m_Rows[iCursor].cyHeight) / 2);

		//	Figure out the actual position of the cursor row (relative to the
		//	rect).

		int yCursor;

		//	If the cursor is in the top part of the list
		if (m_Rows[iCursor].yPos < yIdeal)
			yCursor = m_Rows[iCursor].yPos;

		//	If the total number of lines is less than the whole rect
		else if (m_cyTotalHeight < RectHeight(rcRect))
			yCursor = m_Rows[iCursor].yPos;

		//	If the cursor is in the bottom part of the list
		else if ((m_cyTotalHeight - m_Rows[iCursor].yPos) < (RectHeight(rcRect) - yIdeal))
			yCursor = (RectHeight(rcRect) - (m_cyTotalHeight - m_Rows[iCursor].yPos));

		//	The cursor is in the middle of the list
		else
			yCursor = yIdeal;

		//	Figure out the item position at which we start painting

		int iStart = FindRow(m_Rows[iCursor].yPos - yCursor);
		ASSERT(iStart != -1);
		if (iStart == -1)
			iStart = 0;

		int yStart = yCursor - (m_Rows[iCursor].yPos - m_Rows[iStart].yPos);

		//	Compute y offset of first row (so that we can handle clicks later)

		m_yFirst = yStart - m_Rows[iStart].yPos;

		//	Paint

		int y = rcRect.top + yStart;
		int iPos = iStart;
		bool bPaintSeparator = false;
		RECT rcItem;

		while (y < rcRect.bottom && iPos < m_Rows.GetCount())
			{
			//	Paint previous separator

			if (bPaintSeparator)
				{
				Dest.Fill(rcItem.left + BORDER_RADIUS,
						rcItem.bottom - 1,
						RectWidth(rcItem) - (BORDER_RADIUS * 2),
						1,
						CG32bitPixel(50,50,50));
				}
			else
				bPaintSeparator = true;

			//	Paint only if we have a valid entry. Sometimes we can
			//	start at an invalid entry because we're scrolling.

			if (iPos >= 0)
				{
				m_pListData->SetCursor(iPos);

				rcItem.top = y;
				rcItem.left = rcRect.left;
				rcItem.bottom = y + m_Rows[iPos].cyHeight;
				rcItem.right = rcRect.right;

				//	See if we need to paint the cursor

				bool bIsCursor = (iPos == iCursor);

				//	Paint selection background (if selected)

				if (bIsCursor)
					{
					bPaintCursor = true;
					bPaintSeparator = false;
					rcCursor = rcItem;

					CGDraw::RoundedRect(Dest, 
							rcCursor.left,
							rcCursor.top,
							RectWidth(rcCursor),
							RectHeight(rcCursor),
							BORDER_RADIUS,
							m_rgbBackColor);
					}

				//	Paint item

				switch (m_iType)
					{
					case listCustom:
						PaintCustom(Dest, rcItem, bIsCursor);
						break;

					case listItem:
						PaintItem(Dest, m_pListData->GetItemAtCursor(), rcItem, bIsCursor);
						break;
					}
				}

			//	Next

			y += m_Rows[iPos].cyHeight;
			iPos++;
			}

		//	Done

		m_pListData->SetCursor(iCursor);
		}

	//	Paint a frame

	CGDraw::RoundedRectOutline(Dest,
			rcRect.left,
			rcRect.top,
			RectWidth(rcRect),
			RectHeight(rcRect),
			BORDER_RADIUS,
			1,
			CG32bitPixel(80,80,80));

	if (bPaintCursor)
		{
		CGDraw::RoundedRectOutline(Dest,
				rcCursor.left + 1,
				rcCursor.top + 1,
				RectWidth(rcCursor) - 2,
				RectHeight(rcCursor) - 2,
				BORDER_RADIUS,
				SELECTION_WIDTH,
				m_VI.GetColor(colorAreaDialogHighlight));
		}
	}
Пример #24
0
void CGTextArea::PaintText (CG32bitImage &Dest, const RECT &rcRect)

//	PaintText
//
//	Paint plain text

	{
	//	Paint the text

	if (m_pFont)
		{
		//	If we haven't justified the text for this size, do it now

		if (m_cxJustifyWidth != RectWidth(rcRect))
			{
			m_cxJustifyWidth = RectWidth(rcRect);
			m_Lines.DeleteAll();
			m_pFont->BreakText(m_sText, m_cxJustifyWidth, &m_Lines, CG16bitFont::SmartQuotes);
			}

		//	Compute the rect within which we draw the text

		RECT rcText = rcRect;
		if (m_bEditable)
			{
			int iVSpacing = (RectHeight(rcRect) - m_pFont->GetHeight()) / 2;
			rcText.left += iVSpacing;
			rcText.right -= iVSpacing;
			rcText.top += iVSpacing;
			rcText.bottom -= iVSpacing;
			}

		//	Clip to text rect

		RECT rcOldClip = Dest.GetClipRect();
		Dest.SetClipRect(rcText);

		//	Figure out how many lines fit in the rect

		int iMaxLineCount = RectHeight(rcText) / m_pFont->GetHeight();

		//	If there are too many lines, and we're editable, start at the end

		int iStart = 0;
		if (m_bEditable && iMaxLineCount < m_Lines.GetCount())
			iStart = m_Lines.GetCount() - iMaxLineCount;

		//	Paint each line

		int x = rcText.left;
		int y = rcText.top;
		for (int i = iStart; i < m_Lines.GetCount(); i++)
			{
			CString sLine = m_Lines[i];

			//	Trim the last space in the line, if necessary

			char *pPos = sLine.GetASCIIZPointer();
			if (sLine.GetLength() > 0 && pPos[sLine.GetLength() - 1] == ' ')
				sLine = strTrimWhitespace(sLine);

			//	Alignment

			int xLine;
			if (m_dwStyles & alignCenter)
				{
				int cxWidth = m_pFont->MeasureText(sLine);
				xLine = x + (RectWidth(rcText) - cxWidth) / 2;
				}
			else if (m_dwStyles & alignRight)
				{
				int cxWidth = m_pFont->MeasureText(sLine);
				xLine = x + (RectWidth(rcRect) - cxWidth);
				}
			else
				xLine = x;

			//	Paint

			if (HasEffects())
				m_pFont->DrawTextEffect(Dest, xLine, y, m_rgbColor, sLine, GetEffectCount(), GetEffects());
			else
				Dest.DrawText(xLine, y, *m_pFont, m_rgbColor, sLine);

			//	Next

			y += m_pFont->GetHeight() + m_cyLineSpacing;
			if (y >= rcText.bottom)
				break;
			}

		//	Paint the cursor

		if (m_bEditable && m_iCursorLine >= iStart)
			{
			int cxPos = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(CString(m_Lines[m_iCursorLine].GetASCIIZPointer(), m_iCursorPos, true)) : 0);
			int y = rcText.top + (m_iCursorLine - iStart) * (m_pFont->GetHeight() + m_cyLineSpacing);
			int x = rcText.left;
			if (m_dwStyles & alignCenter)
				{
				int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0);
				x += ((RectWidth(rcText) - cxWidth) / 2) + cxPos;
				}
			else if (m_dwStyles & alignRight)
				{
				int cxWidth = (m_iCursorLine < m_Lines.GetCount() ? m_pFont->MeasureText(m_Lines[m_iCursorLine]) : 0);
				x += (RectWidth(rcText) - cxWidth) + cxPos;
				}
			else
				x += cxPos;

			if (((m_iTick / 30) % 2) > 0)
				{
				Dest.Fill(x, y, 2, m_pFont->GetHeight(), RGB_CURSOR);
				}
			}

		//	Restore clip

		Dest.SetClipRect(rcOldClip);
		}
	}
Пример #25
0
void CGButtonArea::Paint (CG32bitImage &Dest, const RECT &rcRect)

//	Paint
//
//	Handle paint

	{
	int i;

	//	Paint the background

	CG32bitPixel rgbBackColor = ((m_bMouseOver && !m_bDisabled) ? m_rgbBackColorHover : (m_bDisabled ? CG32bitPixel(m_rgbBackColor, 0xC0) : m_rgbBackColor));
	if (!rgbBackColor.IsNull())
		{
		if (m_iBorderRadius > 0)
			{
			CGDraw::RoundedRect(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_iBorderRadius, rgbBackColor);
			CGDraw::RoundedRectOutline(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_iBorderRadius, 1, m_rgbBorderColor);
			}
		else
			Dest.Fill(rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), rgbBackColor);
		}

	//	Paint the label

	int xPaint = rcRect.left + m_rcPadding.left;
	int yPaint = rcRect.top + m_rcPadding.top;
	if (m_pLabelFont)
		{
		//	If we're disabled, paint gray

		if (m_bDisabled)
			Dest.DrawText(xPaint,
					yPaint,
					*m_pLabelFont,
					RGB_DISABLED_TEXT,
					m_sLabel);

		//	If we have a prefix accelerator, draw that

		else if (!m_sAccelerator.IsBlank())
			{
			//	Measure the size of the accelerator

			int cyAccel;
			int cxAccel = m_pLabelFont->MeasureText(m_sAccelerator, &cyAccel);

			//	We draw a rounded-rect box

			int cxBox = cxAccel + (2 * ACCEL_INNER_PADDING);
			int cyBox = cyAccel + 1;
			CGDraw::RoundedRect(Dest, xPaint, yPaint, cxBox, cyBox, ACCEL_BORDER_RADIUS, m_rgbAccelColor);

			//	Draw the text

			Dest.DrawText(xPaint + ACCEL_INNER_PADDING, yPaint, *m_pLabelFont, CG32bitPixel(0, 0, 0), m_sAccelerator);

			//	Now draw the rest of the label

			Dest.DrawText(xPaint + cxBox + (2 * ACCEL_INNER_PADDING), yPaint, *m_pLabelFont, m_rgbLabelColor, m_sLabel);
			}

		//	If we have an accelerator, paint in pieces

		else if (m_iAccelerator != -1)
			{
			char *pPos = m_sLabel.GetASCIIZPointer();
			int x = xPaint;

			if (m_iAccelerator > 0)
				Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbLabelColor, CString(pPos, m_iAccelerator, true), 0, &x);

			Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbAccelColor, CString(pPos + m_iAccelerator, 1, true), 0, &x);
			Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbLabelColor, CString(pPos + m_iAccelerator + 1, m_sLabel.GetLength() - m_iAccelerator - 1, true));
			}
		else
			Dest.DrawText(xPaint,
					yPaint,
					*m_pLabelFont,
					m_rgbLabelColor,
					m_sLabel);

		yPaint += m_pLabelFont->GetHeight();
		}

	//	Paint the description

	if (m_pDescFont)
		{
		for (i = 0; i < m_Lines.GetCount(); i++)
			{
			Dest.DrawText(xPaint,
					yPaint,
					*m_pDescFont,
					m_rgbDescColor,
					m_Lines[i]);

			yPaint += m_pDescFont->GetHeight();
			}
		}
	}
Пример #26
0
void CEffectEntry::GetImage (const CCompositeImageSelector &Selector, CObjectImageArray *retImage)

//	GetImage
//
//	Fills in the image

	{
	//	Short circuit

	if (m_pEffect.IsEmpty())
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Create a painter

	CCreatePainterCtx Ctx;
	IEffectPainter *pPainter = m_pEffect->CreatePainter(Ctx);
	if (pPainter == NULL)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Get the painter bounds

	RECT rcBounds;
	pPainter->GetBounds(&rcBounds);
	int cxWidth = RectWidth(rcBounds);
	int cyHeight = RectHeight(rcBounds);

	//	Manual compositing

	bool bCanComposite = pPainter->CanPaintComposite();

	//	Create a resulting image

	CG32bitImage *pDest = new CG32bitImage;
	pDest->Create(cxWidth, cyHeight, CG32bitImage::alpha8, (bCanComposite ? CG32bitPixel::Null() : CG32bitPixel(0)));

	//	Set up paint context

	SViewportPaintCtx PaintCtx;

	//	Since we don't have an object, we use the viewport center to indicate
	//	the center of the object.

	PaintCtx.xCenter = -rcBounds.left;
	PaintCtx.yCenter = -rcBounds.top;

	//	Paint

	pPainter->PaintComposite(*pDest, (cxWidth / 2), (cyHeight / 2), PaintCtx);

	//	Initialize an image

	RECT rcFinalRect;
	rcFinalRect.left = 0;
	rcFinalRect.top = 0;
	rcFinalRect.right = cxWidth;
	rcFinalRect.bottom = cyHeight;

	CObjectImageArray Comp;
	Comp.Init(pDest, rcFinalRect, 0, 0, true);

	//	Done

	retImage->TakeHandoff(Comp);
	pPainter->Delete();
	}
Пример #27
0
void GenerateTopologyMap (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i, j;

	STopologyMapCtx Ctx;

	//	Initialize the output

	COutputChart Output;
	Output.SetStyleFont(STYLE_NAME, pCmdLine->GetAttribute(CONSTLIT("font")));
	Output.SetStyleColor(STYLE_NAME, CG32bitPixel(0xFF, 0xFF, 0xFF));

	Output.SetOutputFilespec(pCmdLine->GetAttribute(CONSTLIT("output")));

	//	Get the topology node

	CTopologyNode *pFirstNode = Universe.GetFirstTopologyNode();
	if (pFirstNode == NULL)
		{
		printf("ERROR: Unable to find topology node.\n");
		return;
		}

	//	Get the system map for the node

	Ctx.pMap = pFirstNode->GetDisplayPos();
	if (Ctx.pMap == NULL)
		{
		printf("ERROR: No system map for node %s.\n", pFirstNode->GetID().GetASCIIZPointer());
		return;
		}

	//	Create a background image

	CG32bitImage *pImage = Ctx.pMap->CreateBackgroundImage();

	//	Create the output

	Output.SetContentSize((pImage ? pImage->GetWidth() : 1024), (pImage ? pImage->GetHeight() : 1024));
	CG32bitImage &Dest = Output.GetOutputImage();

	//	Blt

	if (pImage)
		Dest.Blt(0, 0, pImage->GetWidth(), pImage->GetHeight(), *pImage, 0, 0);

	//	Done with background image

	delete pImage;
	pImage = NULL;

	//	Compute the size of the map (in pixels)

	Ctx.cxMap = Dest.GetWidth();
	Ctx.cyMap = Dest.GetHeight();
	Ctx.xCenter = Ctx.cxMap / 2;
	Ctx.yCenter = Ctx.cyMap / 2;

	//	Loop over all nodes and clear marks on the ones that we need to draw

	for (i = 0; i < Universe.GetTopologyNodeCount(); i++)
		{
		CTopologyNode *pNode = Universe.GetTopologyNode(i);
			
		int xPos, yPos;
		pNode->SetMarked(pNode->GetDisplayPos(&xPos, &yPos) != Ctx.pMap 
				|| pNode->IsEndGame());
		}

	//	Paint the nodes

	for (i = 0; i < Universe.GetTopologyNodeCount(); i++)
		{
		CTopologyNode *pNode = Universe.GetTopologyNode(i);
		if (!pNode->IsMarked())
			{
			int xPos, yPos;
			pNode->GetDisplayPos(&xPos, &yPos);

			//	Convert to view coordinates

			int x = Ctx.xCenter + xPos;
			int y = Ctx.yCenter - yPos;

			//	Draw gate connections

			for (j = 0; j < pNode->GetStargateCount(); j++)
				{
				CTopologyNode *pDestNode = pNode->GetStargateDest(j);
				if (pDestNode && !pDestNode->IsMarked())
					{
					int xPos, yPos;
					pDestNode->GetDisplayPos(&xPos, &yPos);

					int xDest = Ctx.xCenter + xPos;
					int yDest = Ctx.yCenter - yPos;

					Dest.DrawLine(x, y, xDest, yDest, STARGATE_LINE_WIDTH, STARGATE_LINE_COLOR);
					}
				}

			//	Draw star system

			DrawNode(Ctx, Output, pNode, x, y);

			pNode->SetMarked();
			}
		}

	//	Done

	Output.Output();
	}
Пример #28
0
CG32bitImage *CSystemMap::CreateBackgroundImage (void)

//	CreateBackgroundImage
//
//	Creates an image containing the map.
//	Caller is responsible for freeing the returned image.

	{
	int i;

	CG32bitImage *pImage = g_pUniverse->GetLibraryBitmapCopy(m_dwBackgroundImage);
	if (pImage == NULL)
		return NULL;

	int xCenter = pImage->GetWidth() / 2;
	int yCenter = pImage->GetHeight() / 2;

	//	Paint all annotations

	if (m_Annotations.GetCount() > 0)
		{
		SViewportPaintCtx Ctx;

		for (i = 0; i < m_Annotations.GetCount(); i++)
			{
			SMapAnnotation *pAnnotation = &m_Annotations[i];

			Ctx.iTick = pAnnotation->iTick;
			Ctx.iRotation = pAnnotation->iRotation;

			pAnnotation->pPainter->Paint(*pImage, xCenter + pAnnotation->xOffset, yCenter - pAnnotation->yOffset, Ctx);
			}
		}

#ifdef DEBUG
#if 0
	//	Test noise function
	CG32bitImage Alpha;
	Alpha.CreateBlankAlpha(pImage->GetWidth(), pImage->GetHeight());
	DrawNebulosity8bit(Alpha, 0, 0, pImage->GetWidth(), pImage->GetHeight(), 256, 0, 255);

	pImage->Fill(0, 0, pImage->GetWidth(), pImage->GetHeight(), 0);
	pImage->FillMask(0, 0, pImage->GetWidth(), pImage->GetHeight(), Alpha, CG32bitPixel(255, 255, 255), 0, 0);
#endif
#endif

	return pImage;
	}
Пример #29
0
void TestPolygons (CUniverse &Universe, CXMLElement *pCmdLine)
{
    int i;

    const int FRAME_WIDTH = 256;
    const int FRAME_HEIGHT = 256;
    const int OUTPUT_WIDTH = FRAME_WIDTH * 2;
    const int OUTPUT_HEIGHT = FRAME_HEIGHT;

    //	Options

    int iCount = pCmdLine->GetAttributeInteger(CONSTLIT("count"));
    if (iCount == 0)
        iCount = 1000;

    int iBltCount = Max(1, iCount / 10);

    //	Create the output image

    CG32bitImage Output;
    Output.Create(OUTPUT_WIDTH, OUTPUT_HEIGHT, CG32bitImage::alpha8);

    //	Create a regular polygon

    const int iSides = 17;
    const Metric rRadius = 100.0;
    const Metric rAngleStep = (TAU / iSides);

    TArray<CVector> Shape1;
    Shape1.InsertEmpty(iSides);
    for (i = 0; i < iSides; i++)
        Shape1[i] = CVector::FromPolar(i * rAngleStep, rRadius);

    //	Create a point array, which we'll use for the binary region

    SPoint Shape1Points[iSides];
    for (i = 0; i < iSides; i++)
    {
        Shape1Points[i].x = (int)Shape1[i].GetX();
        Shape1Points[i].y = (int)Shape1[i].GetY();
    }

    //	Create a path

    CGPath Shape1Path;
    Shape1Path.Init(Shape1);

    //	We do timing tests first

    TNumberSeries<Metric> Timing;

    //	Time rasterization of a binary region

    const int CALLS_PER_SAMPLE = 1000;
    const int BLTS_PER_SAMPLE = 100;
    DWORD dwStart = ::GetTickCount();
    for (i = 0; i < iCount; i++)
    {
        CG16bitBinaryRegion Region;
        Region.CreateFromPolygon(iSides, Shape1Points);

        if (((i + 1) % CALLS_PER_SAMPLE) == 0)
            Timing.Insert((Metric)::sysGetTicksElapsed(dwStart, &dwStart));
    }

    printf("CG16bitBinaryRegion::CreateFromPolygon: %s ms per %d\n", (LPSTR)strFromDouble(Timing.GetMean()), CALLS_PER_SAMPLE);

    //	Time rasterization of path

    Timing.DeleteAll();
    dwStart = ::GetTickCount();
    for (i = 0; i < iCount; i++)
    {

        CGRegion Region;
        Shape1Path.Rasterize(&Region, 1);

        if (((i + 1) % CALLS_PER_SAMPLE) == 0)
            Timing.Insert((Metric)::sysGetTicksElapsed(dwStart, &dwStart));
    }

    printf("CGPath::Rasterize: %s ms per %d\n", (LPSTR)strFromDouble(Timing.GetMean()), CALLS_PER_SAMPLE);

    //	Create the regions

    CG16bitBinaryRegion Shape1BinaryRegion;
    Shape1BinaryRegion.CreateFromPolygon(iSides, Shape1Points);

    CGRegion Shape1Region;
    Shape1Path.Rasterize(&Shape1Region, 4);

    //	Time to blt

    Timing.DeleteAll();
    dwStart = ::GetTickCount();
    for (i = 0; i < iBltCount; i++)
    {
        CGDraw::Region(Output, (FRAME_WIDTH / 2), (FRAME_HEIGHT / 2), Shape1BinaryRegion, CG32bitPixel(255, 255, 255));

        if (((i + 1) % BLTS_PER_SAMPLE) == 0)
            Timing.Insert((Metric)::sysGetTicksElapsed(dwStart, &dwStart));
    }

    printf("CGDraw::Region (CG16bitBinaryRegion): %s ms per %d\n", (LPSTR)strFromDouble(Timing.GetMean()), BLTS_PER_SAMPLE);

    Timing.DeleteAll();
    dwStart = ::GetTickCount();
    for (i = 0; i < iBltCount; i++)
    {
        CGDraw::Region(Output, (FRAME_WIDTH / 2), (FRAME_HEIGHT / 2), Shape1Region, CG32bitPixel(255, 255, 255));

        if (((i + 1) % BLTS_PER_SAMPLE) == 0)
            Timing.Insert((Metric)::sysGetTicksElapsed(dwStart, &dwStart));
    }

    printf("CGDraw::Region (CGRegion): %s ms per %d\n", (LPSTR)strFromDouble(Timing.GetMean()), BLTS_PER_SAMPLE);

    //	Clear

    Output.Fill(CG32bitPixel(0, 0, 0));

    //	Blt result

    int x = 0;
    int y = 0;
    CGDraw::Region(Output, x + (FRAME_WIDTH / 2), y + (FRAME_HEIGHT / 2), Shape1BinaryRegion, CG32bitPixel(255, 255, 255));

    x = FRAME_WIDTH;
    CGDraw::Region(Output, x + (FRAME_WIDTH / 2), y + (FRAME_HEIGHT / 2), Shape1Region, CG32bitPixel(255, 255, 255));

    //	Copy to clipboard

    OutputImage(Output, NULL_STR);
}
Пример #30
0
void CCompositeEntry::GetImage (const CCompositeImageSelector &Selector, CObjectImageArray *retImage)

//	GetImage
//
//	Fills in the image

	{
	int i;

	//	Null case

	if (m_Layers.GetCount() == 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	//	Get all the layers

	TArray<CObjectImageArray> Result;
	Result.InsertEmpty(m_Layers.GetCount());
	for (i = 0; i < m_Layers.GetCount(); i++)
		m_Layers[i]->GetImage(Selector, &Result[i]);

	//	Create the composited image
	//
	//	First we need to determine the size of the final image, based
	//	on the size and position of each layer.

	int xMin = 0;
	int xMax = 0;
	int yMin = 0;
	int yMax = 0;

	for (i = 0; i < m_Layers.GetCount(); i++)
		{
		CObjectImageArray &LayerImage = Result[i];
		const RECT &rcRect = LayerImage.GetImageRect();

		int xImageOffset = 0;
		int yImageOffset = 0;

		int xMaxImage = (RectWidth(rcRect) / 2) + xImageOffset;
		int xMinImage = xMaxImage - RectWidth(rcRect);
		int yMaxImage = (RectHeight(rcRect) / 2) + yImageOffset;
		int yMinImage = yMaxImage - RectHeight(rcRect);

		xMin = Min(xMin, xMinImage);
		xMax = Max(xMax, xMaxImage);
		yMin = Min(yMin, yMinImage);
		yMax = Max(yMax, yMaxImage);
		}

	//	Create destination image

	int cxWidth = xMax - xMin;
	int cyHeight = yMax - yMin;
	if (cxWidth <= 0 || cyHeight <= 0)
		{
		*retImage = EMPTY_IMAGE;
		return;
		}

	CG32bitImage *pComp = new CG32bitImage;
	pComp->Create(cxWidth, cyHeight, CG32bitImage::alpha1);

	int xCenter = cxWidth / 2;
	int yCenter = cyHeight / 2;

	//	Blt on the destination

	for (i = 0; i < m_Layers.GetCount(); i++)
		{
		CObjectImageArray &LayerImage = Result[i];
		const RECT &rcRect = LayerImage.GetImageRect();

		//	Paint the image

		LayerImage.PaintImage(*pComp,
				xCenter,
				yCenter,
				0,
				0);
		}

	//	Initialize an image

	RECT rcFinalRect;
	rcFinalRect.left = 0;
	rcFinalRect.top = 0;
	rcFinalRect.right = cxWidth;
	rcFinalRect.bottom = cyHeight;

	CObjectImageArray Comp;
	Comp.Init(pComp, rcFinalRect, 0, 0, true);

	//	Done

	retImage->TakeHandoff(Comp);
	}