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); } }
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)); } } }
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); }
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; }
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; } }
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())); }
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); }
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()); }
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(); } }
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); }
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)); } }
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++; }
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; }
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); }
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; }
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); }
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; } } } }
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); }
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; }
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)); } }
void CExtensionNavigator::DrawTitleBar(CG32bitImage &Screen) { Screen.DrawText(m_AssociatedPanel.GetOriginX() + 10, m_AssociatedPanel.GetOriginY() + 10, m_HeadingFont, m_HeadingColor, CONSTLIT("Extension Navigator")); }
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 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)); } }
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 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(); } } }
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(); }
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(); }
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 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); }
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); }