Example #1
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);
	}
Example #2
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));
		}
	}
Example #3
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);
		}
	}
Example #4
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;
	}
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;
	}
Example #6
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);
	}
Example #7
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));
		}
	}
Example #8
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);
		}
	}
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);
}
Example #10
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();
			}
		}
	}
Example #11
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;
		}
	}
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));
		}
	}