void Sprite::OnDraw( Gdiplus::Graphics &g, const Gdiplus::RectF &rcDirty ) { if (!m_bVisible) { return; // 子节点也不会被绘制 } // 前序遍历 让父节点先绘制 //Gdiplus::RectF rc = GetRect(); //if (10 == rc.Width && 10 == rc.Height) //{ // LOGW(<<L"Orignal Size 10 10"); // 检查下有没有多余的重绘 //} if (m_bClipChildren) { Gdiplus::RectF rcClip = GetRect(); rcClip.X = 0.0f; rcClip.Y = 0.0f; g.SetClip(rcClip); } PaintEvent ev; ev.graphics = &g; ev.rcDirty = rcDirty; SendNotify(ePaint, &ev); //this->ClientDraw(g, rcDirty); Sprite *sp = m_firstChild; while(sp) { // 如果需要重绘部分矩形和sp相交则重画它 否则不重画 // 这里还有个问题就是 父矩形必须比子矩形要大 否则可能父的相交不到 而子的相交的到 // 可能要强制这一原理 类似于浏览器 会撑大 Gdiplus::RectF rc2 = sp->GetRect(); Gdiplus::RectF rcAbs = sp->GetAbsRect(); rcAbs.X -= 0.5f; // FIXME 有时无法得到重画导致边界1像素消失 rcAbs.Y -= 0.5f; rcAbs.Width += 1.0f; rcAbs.Height += 1.0f; if (rcDirty.IntersectsWith(rcAbs)) { g.TranslateTransform(rc2.X, rc2.Y); sp->OnDraw(g, rcDirty); g.TranslateTransform(-rc2.X, -rc2.Y); } sp = sp->m_nextSibling; } if (m_bClipChildren) { g.ResetClip(); } }
void CTabsControl::DrawItem(CTabControl *item, Gdiplus::Graphics &g) { CRect rect = ItemRect(item); g.ResetTransform(); g.TranslateTransform((REAL)rect.left, (REAL)rect.top); RectF rf(0.0f, 0.0f, (REAL)rect.Width(), (REAL)rect.Height()); RectF rx; if(item->selected) { #define shadowb 10 CDIB tmp; tmp.Resize(rect.Width() + shadowb * 2, rect.Height() + shadowb * 2); if(tmp.Ready()) { Graphics gt(tmp.bmp); RectF rx(0, 0, (REAL)tmp.Width(), (REAL)tmp.Height()); GraphicsPath *path = new GraphicsPath(); path->AddLine(rx.X + shadowb, rx.Y + rx.Height - shadowb, rx.X + rx.Width - 2 - shadowb, rx.Y + rx.Height - shadowb); path->AddLine(rx.X + rx.Width - 2 - shadowb, rx.Y + rx.Height - shadowb, rx.X + rx.Width - 2, rx.Y); path->AddLine(rx.X + rx.Width - 2, rx.Y, rx.X + rx.Width, rx.Y + rx.Height); path->AddLine(rx.X + rx.Width, rx.Y + rx.Height, rx.X, rx.Y + rx.Height); path->AddLine(rx.X, rx.Y, rx.X + shadowb, rx.Y + rx.Height - shadowb); path->CloseFigure(); SolidBrush brush(0xff000000); gt.FillPath(&brush, path); tmp.Blur(tmp.Rect(), CRect(0, 0, 0, 0), shadowb); g.DrawImage(tmp.bmp, rf, shadowb, shadowb, rf.Width, rf.Height, UnitPixel); delete path; } } Font font(L"Arial", item->selected ? 8.0f : 8.0f); StringFormat *stringFormat = new StringFormat(); stringFormat->SetAlignment(StringAlignmentCenter); stringFormat->SetLineAlignment(StringAlignmentCenter); stringFormat->SetTrimming(StringTrimmingEllipsisCharacter); stringFormat->SetFormatFlags(StringFormatFlagsLineLimit); if(item->icon->Ready()) { g.SetInterpolationMode(InterpolationModeBicubic); rx = rf; rx.Y += 6; rx.Height -= (20 + rx.Y); rx.Width = rx.Height; rx.X += (rf.Width - rx.Width) / 2; if(item->selected) { rx.Y++; #define shadow 5 CDIB tmp; tmp.Resize(item->icon->Width(), item->icon->Height()); if(tmp.Ready()) { tmp.Draw(CRect(shadow, shadow, item->icon->Width() - shadow, item->icon->Height() - shadow), item->icon->Rect(), item->icon); DIB_ARGB *p = tmp.scan0; int size = tmp.Width() * tmp.Height(); for(int i = 0; i < size; i++, p++) { p->r = 0; p->g = 0; p->b = 0; } tmp.Blur(tmp.Rect(), CRect(0, 0, 0, 0), shadow); g.DrawImage(tmp.bmp, RectF(rx.X, rx.Y + shadow, rx.Width, rx.Height)); } tmp.Assign(item->icon); /*if(tmp.Ready()) { DIB_ARGB *p = tmp.scan0; int size = tmp.Width() * tmp.Height(); for(int i = 0; i < size; i++, p++) { p->r = 0x6f; p->g = 0xa6; p->b = 0xde; } }*/ g.DrawImage(tmp.bmp, rx); } else { g.DrawImage(item->icon->bmp, rx); } } SolidBrush brush(0xff000000); rx = rf; rx.Height = 20; rx.Y = rf.Height - rx.Height; rx.Y++; g.DrawString(item->text.GetBuffer(), item->text.GetLength(), &font, rx, stringFormat, &brush); brush.SetColor(item->selected && false ? 0xff6fa6de : 0xfff0f0f0); rx.Y--; g.DrawString(item->text.GetBuffer(), item->text.GetLength(), &font, rx, stringFormat, &brush); delete stringFormat; //POSITION p = items.Find(item); //items.GetNext(p); //if(p) { RectF rx = rf; rx.X += rx.Width - 1; rx.Width = 1; LinearGradientBrush brush(rx, Color(140, 0x69, 0x69, 0x69), Color(0x69, 0x69, 0x69), LinearGradientModeVertical); g.FillRectangle(&brush, rx); } }
void CanvasGdiplus::TranslateInt(int x, int y) { Gdiplus::Graphics* current = GetCurrentGraphics(); current->TranslateTransform(static_cast<Gdiplus::REAL>(x), static_cast<Gdiplus::REAL>(y)); }
void GameManager::Render(Gdiplus::Graphics& canvas, const CRect& clientRect) { //////////////////////////////////////////////////////////////////////////////// // Begin example code // Save the current transformation of the scene Gdiplus::Matrix transform; canvas.GetTransform(&transform); // Offset by the negative of the player direction canvas.TranslateTransform(-(Gdiplus::REAL)playerPtr->location.X, -(Gdiplus::REAL)playerPtr->location.Y); int numRows = clientRect.Height() / CellSize; int numCols = clientRect.Width() / CellSize; // draw horizontal lines for grid for (int row = 0; row < numRows; ++row) { Vector2i start = Vector2i(0, row * CellSize); Vector2i end = Vector2i(clientRect.Width(), row * CellSize); GameFrameworkInstance.DrawLine(canvas, start, end, Gdiplus::Color::White); } // draw vertical lines for grid for (int col = 0; col < numCols; ++col) { Vector2i start = Vector2i(col * CellSize, 0); Vector2i end = Vector2i(col * CellSize, clientRect.Height()); GameFrameworkInstance.DrawLine(canvas, start, end, Gdiplus::Color::White); } // Draw all of the objects for (GameObject* objectPtr : gameObjects) { objectPtr->Render(canvas); } // Render method demonstration (You can remove all of this code) GameFrameworkInstance.DrawLine(canvas, Vector2i(200, 200), Vector2i(400, 200), Gdiplus::Color::White); GameFrameworkInstance.DrawRectangle(canvas, AABBi(Vector2i(10, 110), Vector2i(100, 200)), false, Gdiplus::Color::White); GameFrameworkInstance.DrawRectangle(canvas, AABBi(Vector2i(200, 110), Vector2i(300, 200)), true, Gdiplus::Color::White); //// restore the transform //canvas.SetTransform(&transform); GameFrameworkInstance.DrawCircle(canvas, Vector2i(200, 200), 50, false, Gdiplus::Color::White); GameFrameworkInstance.DrawCircle(canvas, Vector2i(400, 200), 50, true, Gdiplus::Color::White); GameFrameworkInstance.DrawText(canvas, Vector2i(10, 300), 12, "Arial", "Hello World!", Gdiplus::Color::White); // Load the image file Untitled.png from the Images folder. Give it the unique name of Image1 ImageWrapper* image1 = GameFrameworkInstance.GetLoadedImage(Image1); GameFrameworkInstance.DrawImage(canvas, Vector2i(400, 400), image1); // Restore the transformation of the scene canvas.SetTransform(&transform); // End example code //////////////////////////////////////////////////////////////////////////////// // Build Menu Vector2i dimensions = GameManagerInstance.GetScreenDimensions(); Vector2i centrePoint = dimensions * 0.1f; GameFrameworkInstance.DrawRectangle(canvas, AABBi(Vector2i(0, 0) + centrePoint, Vector2i(150, 500) + centrePoint), true, Gdiplus::Color::Gray); GameFrameworkInstance.DrawText(canvas, Vector2i(10, 10) + centrePoint, 12, "Arial", "[1] Wall", Gdiplus::Color::White); GameFrameworkInstance.DrawText(canvas, Vector2i(10, 35) + centrePoint, 12, "Arial", "[2] Damage Zone", Gdiplus::Color::White); GameFrameworkInstance.DrawText(canvas, Vector2i(10, 60) + centrePoint, 12, "Arial", "[3] Healing Zone", Gdiplus::Color::White); }
void Graphics::TranslateTransform(float dx, float dy, MatrixOrder order) { Gdiplus::Graphics* g = reinterpret_cast<Gdiplus::Graphics*>(_private); g->TranslateTransform(dx, dy, order == MatrixOrderPrepend ? Gdiplus::MatrixOrderPrepend : Gdiplus::MatrixOrderAppend); }