Gridlay::Gridlay(ChildCore *core) : Layer(core,NULL) { this->image = NULL; this->gridblock = NULL; this->pattern = NULL; this->x = 0; this->y = 0; this->oldx = 0; this->oldy = 0; this->width = 0; this->height = 0; this->rendered = false; SolidBrush *b = new SolidBrush(CLR_FRAME_LIGHT); this->image = new Bitmap(2 * GRDBGBLOCK,2 * GRDBGBLOCK,Core::getPixelFormat()); Graphics *g = Graphics::FromImage(this->image); g->SetInterpolationMode(InterpolationModeNearestNeighbor); g->Clear(CLR_WHITE); g->FillRectangle(b,GRDBGBLOCK,0,GRDBGBLOCK,GRDBGBLOCK); g->FillRectangle(b,0,GRDBGBLOCK,GRDBGBLOCK,GRDBGBLOCK); delete b; delete g; g = Graphics::FromHWND(this->core->getWindowHandle()); this->pattern = new CachedBitmap((Bitmap *)this->image,g); delete g; }
//************************************************************************* // Method: MeasureDisplayString // Description: Gets the size of a string in pixels // // Parameters: // graphics - the graphics object the string will be measured on // test - the string to measure // font - the font to measure the string in // // Return Value: the size of the string //************************************************************************* SizeF StringTools::MeasureDisplayString(Graphics *graphics, String *text, Font *font) { const int width = 32; Bitmap *bitmap = new Bitmap(width, 1, graphics); SizeF size = graphics->MeasureString(text, font); Graphics *g = Graphics::FromImage(bitmap); int measuredWidth = (int)size.Width; if (g) { g->Clear(Color::White); g->DrawString(String::Concat(text, "|"), font, Brushes::Black, (float)(width - measuredWidth), (float)(0 - (font->Height / 2))); for (int i = width - 1; i >= 0; i--) { measuredWidth--; if (bitmap->GetPixel(i, 0).R == 0) { break; } } } return SizeF((float)measuredWidth, size.Height); }
wxBitmap* gdiplusResize(wxBitmap* bitmap, const FloatSize& size) { IntSize intSize = IntSize(ceilf(size.width()), ceilf(size.height())); if (intSize.width() == bitmap->GetWidth() && intSize.height() == bitmap->GetHeight()) return new wxBitmap(*bitmap); // just return a copy if the asked for the same size wxBitmap* newBitmap = new wxBitmap(intSize.width(), intSize.height(), 32); newBitmap->UseAlpha(); wxMemoryDC memdc(*newBitmap); wxGraphicsContext* gc = wxGraphicsContext::Create(memdc); wxGraphicsBitmap gcbitmap(gc->CreateBitmap(*bitmap)); Graphics* graphics = (Graphics*)gc->GetNativeContext(); graphics->Clear(Gdiplus::Color(0, 0, 0, 0)); // Only use HighQualityBicubic when downsampling. InterpolationMode mode; if (size.width() < (int)bitmap->GetWidth() && size.height() < (int)bitmap->GetHeight()) mode = InterpolationModeHighQualityBicubic; else mode = InterpolationModeBicubic; graphics->SetInterpolationMode(mode); graphics->DrawImage((Bitmap*)gcbitmap.GetNativeBitmap(), 0.0, 0.0, size.width(), size.height()); premultiplyAlpha(*newBitmap); delete gc; return newBitmap; }
TexturePod OverlayText(string message) { InitializeGdi(); PezConfig cfg = PezGetConfig(); // Skip GDI text generation if the string is unchanged: if (message == oc.PreviousMessage) return oc.MessageTexture; oc.PreviousMessage = message; // Create the GDI+ drawing context and set it up: Graphics* gfx = Graphics::FromImage(oc.GdiBitmap); gfx->Clear(Color::Transparent); gfx->SetSmoothingMode(SmoothingModeAntiAlias); gfx->SetInterpolationMode(InterpolationModeHighQualityBicubic); // Select a font: FontFamily fontFamily(L"Trebuchet MS"); const float fontSize = 14; PointF origin(10.0f, 10.0f); StringFormat format(StringAlignmentNear); // Create a path along the outline of the glyphs: GraphicsPath path; path.AddString( wstring(message.begin(), message.end()).c_str(), -1, &fontFamily, FontStyleRegular, fontSize, origin, &format); // Draw some glow to steer clear of crappy AA: for (float width = 0; width < 3; ++width) { Pen pen(Color(64, 0, 0, 0), width); pen.SetLineJoin(LineJoinRound); gfx->DrawPath(&pen, &path); } // Fill the glyphs: SolidBrush brush(Color(50, 100, 200)); gfx->FillPath(&brush, &path); // Lock the raw pixel data and pass it to OpenGL: BitmapData data; oc.GdiBitmap->LockBits(0, ImageLockModeRead, PixelFormat32bppARGB, &data); _ASSERT(data.Stride == sizeof(unsigned int) * cfg.Width); glBindTexture(GL_TEXTURE_2D, oc.MessageTexture.Handle); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cfg.Width, cfg.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.Scan0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); oc.GdiBitmap->UnlockBits(&data); return oc.MessageTexture; }
/* Public functions */ void VGCFontImpTest::run(){ const std::string windowTitle = "Hello world!"; const int WINDOW_WIDTH = 200; const int WINDOW_HEIGHT = 200; VGCFontImp::initializeFontImp(); VGCFontImp::initializeFontImp(); VGCWindow::initializeWindow(windowTitle, WINDOW_WIDTH, WINDOW_HEIGHT); Graphics *graphics = new Graphics(VGCWindow::getHandle(), FALSE); VGCFontImp *font = new VGCFontImp(graphics, "Times New Roman", 24); font->setSize(32); font->setName("Times New Roman"); VGCAssert(32 == font->getSize()); VGCAssert("Times New Roman" == font->getName()); VGCAssert(0 < font->getLineHeight()); VGCAssert(0 < font->getLineWidth("Crap")); VGCAssert(0 == font->getLineWidth("")); const double START_TIME = fGetTime(); while((fGetTime() - START_TIME < DISPLAY_TIME) && VGCWindow::windowIsOpen()){ graphics->Clear(Color(255, 255, 255, 255)); font->render( "Hello world!", VGCColor(255, 255, 0, 0), VGCVector(0, 0), VGCAdjustment(0.0, 0.0)); font->render( "Hello world!", VGCColor(128, 255, 0, 0), VGCVector(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2), VGCAdjustment(0.5, 0.5)); font->render( "Hello world!", VGCColor(64, 255, 0, 0), VGCVector(WINDOW_WIDTH, WINDOW_HEIGHT), VGCAdjustment(1.0, 1.0)); VGCWindow::handleMessages(); Sleep(100); } delete font; delete graphics; VGCWindow::finalizeWindow(); VGCFontImp::finalizeFontImp(); VGCFontImp::finalizeFontImp(); }
// Draw to screen void Game::Draw( Graphics &Graphic ) { Graphic.Clear( ); m_Level.Draw( Graphic ); if ( bDrawDebug ) { m_Level.DrawCollision( Graphic ); } m_Player.Draw( Graphic ); Graphic.RenderTexture( ); }
void IrisBitmap::Clear(){ this->needRefreshTexture = true; //graphics->Clear(Color(100, 100, 100)); Bitmap* tp = this->bitmap->Clone(0, 0, this->width, this->height, PixelFormat32bppARGB); Graphics* tg = new Graphics(tp); delete this->bitmap; tg->Clear(Color(0, 0, 0, 0)); this->bitmap = tp->Clone(0, 0, tp->GetWidth(), tp->GetHeight(), PixelFormat32bppARGB); delete tp; delete tg; }
void FontSheet::BuildFontSheetBitmap(Font& font, Graphics& charGraphics, Bitmap& charBitmap, Graphics& fontSheetGraphics) { WCHAR charString[2] = {' ', 0}; SolidBrush whiteBrush(Color(255, 255, 255, 255)); UINT fontSheetX = 0; UINT fontSheetY = 0; for(UINT i = 0; i < NumChars; ++i) { charString[0] = static_cast<WCHAR>(StartChar + i); charGraphics.Clear(Color(0, 0, 0, 0)); charGraphics.DrawString(charString, 1, &font, PointF(0.0f, 0.0f), &whiteBrush); // Compute tight char horizontal bounds (ignoring empty space). int minX = GetCharMinX(charBitmap); int maxX = GetCharMaxX(charBitmap); int charWidth = maxX - minX + 1; // Move to next row of the font sheet? if(fontSheetX + charWidth >= mTexWidth) { fontSheetX = 0; fontSheetY += static_cast<int>(mCharHeight) + 1; } // Save the rectangle of this character on the texture atlas. mCharRects[i] = CD3D11_RECT(fontSheetX, fontSheetY, fontSheetX + charWidth, fontSheetY + mCharHeight); // The rectangle subset of the source image to copy. fontSheetGraphics.DrawImage(&charBitmap, fontSheetX, fontSheetY, minX, 0, charWidth, mCharHeight, UnitPixel); // next char fontSheetX += charWidth + 1; } }
void View::Paint(Graphics *g) { if (_gbuf == NULL) return; Graphics *gg = Graphics::FromImage(_gbuf); gg->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); gg->Clear(_backcolor); if (_bmp) { gg->DrawImage(_bmp, 0, 0, _bmp->GetWidth(), _bmp->GetHeight()); } for (ClstPtr c = _cl.begin(); c != _cl.end(); c++) (*c)->OnDraw(gg); delete gg; g->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); g->DrawImage(_gbuf, 0, 0); }
Bitmap *Layer::render() { this->locate(); WaitForSingleObject(this->mut_image,INFINITE); int frame = FRAME; Bitmap *scene = NULL; if( this->fulldraw == true ) scene = new Bitmap(this->cwidth + 2*frame,this->cheight + 2*frame); else scene = new Bitmap(this->width,this->height); Graphics *tmpgfx = Graphics::FromImage(scene); Image *tmp = NULL; tmpgfx->Clear(CLR_WHITE); if( this->fulldraw == true ){ if( this->image != NULL ){ double zoom = NULL; int width, height; if( this->scali == NULL ) tmp = this->image; else tmp = this->scali; if( this->fullscreen == false ) tmpgfx->DrawRectangle(this->Pen_Border, this->x - frame, this->y - frame, this->width + frame + 1, this->height + frame + 1); tmpgfx->DrawImage(tmp, Rect(this->x, this->y, this->width, this->height), 0, 0, tmp->GetWidth(), tmp->GetHeight(), UnitPixel); if( this->prev != NULL && this->sidedraw == true ){ if( this->scalp == NULL ) tmp = this->prev; else tmp = this->scalp; width = tmp->GetWidth(); height = tmp->GetHeight(); if( this->scalp == NULL ) zoom = this->getZoom(width,height,this->cwidth,this->cheight); else zoom = ZOOMINIT; int pwidth = (int)(zoom * width); int pheight = (int)(zoom * height); int px = (int)((this->cwidth - pwidth)/2); if( this->sidemode == LEFT && px < 0 ) px = 0; else if( this->sidemode == RIGHT && px < 0 ) px = this->cwidth - pwidth; int py = this->y - pheight - MARGIN - this->offrollVer; if( this->fullscreen == false ) tmpgfx->DrawRectangle(this->Pen_Border, px - frame, py - frame, pwidth + frame + 1, pheight + frame + 1); tmpgfx->DrawImage(tmp,Rect(px,py,pwidth,pheight),0,0, tmp->GetWidth(),tmp->GetHeight(),UnitPixel); } if( this->next != NULL && this->sidedraw == true ){ if( this->scaln == NULL ) tmp = this->next; else tmp = this->scaln; width = tmp->GetWidth(); height = tmp->GetHeight(); if( this->scaln == NULL ) zoom = this->getZoom(width,height,this->cwidth,this->cheight); else zoom = ZOOMINIT; int nwidth = (int)(zoom * width); int nheight = (int)(zoom * height); int nx = (int)((this->cwidth - nwidth)/2); if( this->sidemode == LEFT && nx < 0 ) nx = 0; else if( this->sidemode == RIGHT && nx < 0 ) nx = this->cwidth - nwidth; int ny = this->y + this->height + MARGIN + this->offrollVer; if( this->fullscreen == false ) tmpgfx->DrawRectangle(this->Pen_Border, nx - frame, ny - frame, nwidth + frame + 1, nheight + frame + 1); tmpgfx->DrawImage(tmp,Rect(nx,ny,nwidth,nheight),0,0, tmp->GetWidth(),tmp->GetHeight(),UnitPixel); } } this->x = 0; this->y = 0; this->width = scene->GetWidth(); this->height = scene->GetHeight(); } else { if( this->scali == NULL ) tmp = this->image; else tmp = this->scali; tmpgfx->DrawImage(tmp, Rect(0,0,this->width,this->height), 0,0,tmp->GetWidth(),tmp->GetHeight(), UnitPixel); } ReleaseMutex(this->mut_image); this->fulldraw = true; this->animate(); delete tmpgfx; return scene; }
HICON NewGUI_CreateColorizedIcon(HICON hBase, HICON hOverlay, COLORREF clr, int qSize) { if(hBase == NULL) { ASSERT(FALSE); return NULL; } if(qSize <= 0) qSize = 48; // Large shell icon size Bitmap bmp(qSize, qSize, PixelFormat32bppARGB); Graphics *pg = Graphics::FromImage(&bmp); ASSERT(pg != NULL); VERIFY(pg->Clear(Color::Transparent) == Ok); VERIFY(pg->SetInterpolationMode(InterpolationModeHighQualityBicubic) == Ok); VERIFY(pg->SetSmoothingMode(SmoothingModeHighQuality) == Ok); if(qSize > 32) { Bitmap* pbmpIco = NULL; if(!NewGUI_ExtractVistaIcon(hBase, &pbmpIco)) pbmpIco = Bitmap::FromHICON(hBase); ASSERT(pbmpIco != NULL); pg->DrawImage(pbmpIco, 0, 0, bmp.GetWidth(), bmp.GetHeight()); delete pbmpIco; } else { Bitmap* pbmpIco = Bitmap::FromHICON(hBase); ASSERT(pbmpIco != NULL); pg->DrawImage(pbmpIco, 0, 0, bmp.GetWidth(), bmp.GetHeight()); delete pbmpIco; } if(clr != DWORD_MAX) { BitmapData bd; Rect rect(0, 0, bmp.GetWidth(), bmp.GetHeight()); VERIFY(bmp.LockBits(&rect, ImageLockModeRead | ImageLockModeWrite, PixelFormat32bppARGB, &bd) == Ok); const int nBytes = abs(bd.Stride * static_cast<int>(bmp.GetHeight())); BYTE* pbArgb = (BYTE *)bd.Scan0; float fHue, fSat, fVal; NewGUI_ColorToHsv(clr, &fHue, &fSat, &fVal); for(int i = 0; i < nBytes; i += 4) { if(pbArgb[i + 3] == 0) continue; // Transparent if((pbArgb[i] == pbArgb[i + 1]) && (pbArgb[i] == pbArgb[i + 2])) continue; // Gray COLORREF clrPixel = RGB(pbArgb[i + 2], pbArgb[i + 1], pbArgb[i]); // BGRA float h, s, v; NewGUI_ColorToHsv(clrPixel, &h, &s, &v); COLORREF clrNew = NewGUI_ColorFromHsv(fHue, s, v); pbArgb[i] = GetBValue(clrNew); pbArgb[i + 1] = GetGValue(clrNew); pbArgb[i + 2] = GetRValue(clrNew); } VERIFY(bmp.UnlockBits(&bd) == Ok); } if(hOverlay != NULL) { Bitmap* pOverlay = Bitmap::FromHICON(hOverlay); pg->DrawImage(pOverlay, 0, bmp.GetHeight() / 2, bmp.GetWidth() / 2, bmp.GetHeight() / 2); delete pOverlay; } SAFE_DELETE(pg); HICON hIcon = NULL; VERIFY(bmp.GetHICON(&hIcon) == Ok); return hIcon; }
void Thumblay::subrender() { Graphics *gfx = Graphics::FromImage(this->image); gfx->Clear(CLR_WHITE); Cacher *cacher = this->core->getCacher(); if( cacher != NULL ){ Image *thumb = NULL; Cell *cell = NULL; int i, x, y, mx, my, count; bool top, bot, left, right; right = false; left = false; top = false; bot = false; mx = OVL_MARGIN + 2 * (THB_SMSIZE + THB_SPACE); my = mx; x = y = OVL_MARGIN; count = 0; for( i = -THB_COUNT - this->picker; i <= THB_COUNT - this->picker; i++ ){ cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getCache()->gettoThat(i); if( cell != NULL ){ thumb = cell->getImageThumb(); if( thumb != NULL ){ if( i != 0 ){ gfx->DrawImage(thumb,x,y,THB_SMSIZE,THB_SMSIZE); gfx->DrawRectangle(this->Pen_Border, x, y, THB_SMSIZE, THB_SMSIZE); } else { mx = x + (int)((THB_SIZE - THB_SMSIZE)/4); my = y + (int)((THB_SIZE - THB_SMSIZE)/4); } } if( i == -THB_ROW ) top = true; if( i == THB_ROW ) bot = true; if( i == -1 && cacher->getCache()->isThatHead() == false ) left = true; if( i == 1 && cacher->getCache()->isThatTail() == false ) right = true; } } count++; x += THB_SMSIZE + THB_SPACE; if( count >= THB_ROW ){ x = OVL_MARGIN; y += THB_SMSIZE + THB_SPACE; count = 0; } cacher->unlockCache(); } int frame = 2; cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getThat(); if( cell != NULL ){ thumb = cell->getImageThumb(); if( thumb != NULL ){ gfx->FillRectangle(this->Brush_Back, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawImage(thumb, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawRectangle(this->Pen_Border, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawRectangle( this->Pen_DarkBorder, mx - frame - THB_SIZE/4, my - frame - THB_SIZE/4, THB_SIZE + 2*frame, THB_SIZE + 2*frame ); } } } cacher->unlockCache(); int size = 3; int width = 10; int ax = (int)(mx - frame - THB_SIZE/4); int ay = (int)(my - frame - THB_SIZE/4); int asize = THB_SIZE + 2*frame; Point arrow[3]; if( top == true ){ arrow[0].X = (int)(ax + (THB_SIZE/2) - width); arrow[0].Y = ay; arrow[1].X = (int)(ax + (THB_SIZE/2)); arrow[1].Y = ay - width; arrow[2].X = (int)(ax + (THB_SIZE/2) + width); arrow[2].Y = ay; gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( bot == true ){ arrow[0].X = (int)(ax + (THB_SIZE/2) - width); arrow[0].Y = ay + asize; arrow[1].X = (int)(ax + (THB_SIZE/2)); arrow[1].Y = ay + asize + width; arrow[2].X = (int)(ax + (THB_SIZE/2) + width); arrow[2].Y = ay + asize; gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( left == true ){ arrow[0].X = ax; arrow[0].Y = (int)(ay + (THB_SIZE/2) - width); arrow[1].X = ax - width; arrow[1].Y = (int)(ay + (THB_SIZE/2)); arrow[2].X = ax; arrow[2].Y = (int)(ay + (THB_SIZE/2) + width); gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( right == true ){ arrow[0].X = ax + asize; arrow[0].Y = (int)(ay + (THB_SIZE/2) - width); arrow[1].X = ax + asize + width; arrow[1].Y = (int)(ay + (THB_SIZE/2)); arrow[2].X = ax + asize; arrow[2].Y = (int)(ay + (THB_SIZE/2) + width); gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } } if( this->ticker > TICKER_OFF ){ int tsize = TICKER_SIZE; int tx,ty; if( this->ticker == 0 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 1 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 2 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } if( this->ticker == 3 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize); } delete gfx; }
void Listlay::subrender() { Graphics *gfx = Graphics::FromImage(this->image); gfx->Clear(CLR_WHITE); Cacher *cacher = this->core->getCacher(); if( cacher != NULL ){ FwCHAR *string = NULL; FwCHAR *name = NULL; Cell *cell = NULL; int i, x, y; bool top, bot, archived = false; top = false; bot = false; x = LST_X; y = LST_Y; for( i = -CACHE_SIZE; i < CACHE_SIZE; i++ ){ cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getCache()->gettoThat(i); if( cell != NULL ){ if( cell->getFile() != NULL ){ name = cell->getFile()->getFileName(); } if( name != NULL ){ if( i == 0 ) gfx->FillRectangle(this->Brush_LiteBack,0,y+1,OVL_SIZE,FONTSIZE+2); string = name; if( cell->getFile()->isArchived() == true ){ if( archived == false ) archived = true; string = new FwCHAR(L"~"); string->mergeWith(name); x = 3*LST_X; } else if( archived == true ){ archived = false; x = LST_X; } gfx->DrawString(string->toWCHAR(), string->toLength(), this->Font_Default, PointF((REAL)x,(REAL)y), this->Brush_DarkBack); if( archived == true ) delete string; } if( i == -1 && cacher->getCache()->isThatHead() == false ) top = true; if( i == 1 && cacher->getCache()->isThatTail() == false ) bot = true; } } cacher->unlockCache(); y += (FONTSIZE + 2); } int size = 3; int width = 20; int ax = (int)(OVL_SIZE/2); int ay = LST_Y; int asize = OVL_SIZE - 2*LST_Y; Point arrow[3]; if( top == true ){ arrow[0].X = ax - width; arrow[0].Y = ay; arrow[1].X = ax; arrow[1].Y = ay - width; arrow[2].X = ax + width; arrow[2].Y = ay; gfx->FillPolygon(this->Brush_LiteBack,arrow,size); } if( bot == true ){ arrow[0].X = ax - width; arrow[0].Y = ay + asize; arrow[1].X = ax; arrow[1].Y = ay + asize + width; arrow[2].X = ax + width; arrow[2].Y = ay + asize; gfx->FillPolygon(this->Brush_LiteBack,arrow,size); } } if( this->ticker > TICKER_OFF ){ int tsize = TICKER_SIZE; int tx,ty; if( this->ticker == 0 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 1 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 2 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } if( this->ticker == 3 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize); } delete gfx; }
HBITMAP prepareBitmap(HWND hwnd, const TCHAR* filepath, int& ow, int& oh) { Bitmap* bmp = new Bitmap(filepath); if (!bmp) return NULL; int iw = bmp->GetWidth(); int ih = bmp->GetHeight(); int fw = GetSystemMetrics(SM_CXSCREEN); int fh = GetSystemMetrics(SM_CYSCREEN); double rw = (double)fw / iw; double rh = (double)fh / ih; int w, h; if (rw > rh) { w = fw; // == iw * rw h = ih * rw; //printf("%dx%d x %lf = %dx%d (%lf:%lf | %dx%d)\n", iw, ih, rw, w, h, rw, rh, fw, fh); } else { w = iw * rh; h = fh; // == ih * rh //printf("%dx%d x %lf = %dx%d (%lf:%lf | %dx%d)\n", iw, ih, rh, w, h, rw, rh, fw, fh); } ow = w; oh = h; BITMAPV5HEADER bi; ZeroMemory(&bi,sizeof(BITMAPV5HEADER)); bi.bV5Size = sizeof(BITMAPV5HEADER); bi.bV5Width = w; bi.bV5Height = h; bi.bV5Planes = 1; bi.bV5BitCount = 32; bi.bV5Compression = BI_BITFIELDS; bi.bV5RedMask = 0x00FF0000; bi.bV5GreenMask = 0x0000FF00; bi.bV5BlueMask = 0x000000FF; bi.bV5AlphaMask = 0xFF000000; void *lpBits; HDC hdc, hmemdc; Graphics* g; HBITMAP hbmp = CreateDIBSection(NULL, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD)0); if (!hbmp) goto error_exit0; hdc = GetDC(hwnd); hmemdc = CreateCompatibleDC(hdc); SelectObject(hmemdc, hbmp); g = new Graphics(hmemdc); if (!g) goto error_exit1; g->Clear(Color::Transparent); g->SetCompositingMode(CompositingModeSourceOver); g->DrawImage(bmp, 0, 0, w, h); delete g; DeleteDC(hmemdc); ReleaseDC(hwnd, hdc); delete bmp; return hbmp; error_exit1: DeleteObject(hbmp); // fall through error_exit0: delete bmp; return NULL; }
bool MainWindow::onMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_INITDIALOG: initBlocks(); return TRUE; case WM_DRAWITEM: { DRAWITEMSTRUCT* dws = reinterpret_cast<DRAWITEMSTRUCT*>(lParam); if(dws->itemAction == ODA_DRAWENTIRE) { Graphics* g = Graphics::FromHDC(dws->hDC); g->SetTextRenderingHint(TextRenderingHintAntiAlias); g->Clear(Color(255, 0, 0, 0)); drawCharacters(g); g->Flush(); delete g; } } return TRUE; case WM_CLOSE: { PostQuitMessage(0); EndDialog(mWindow, 0); } return TRUE; case WM_COMMAND: { if(HIWORD(wParam) == 0) { if(LOWORD(wParam) == ID_FILE_EXIT) { PostQuitMessage(0); EndDialog(mWindow, 0); return TRUE; } else if(LOWORD(wParam) == ID_FILE_SAVEAS) { std::vector<wchar_t> filePath(2048); OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = mWindow; ofn.hInstance = GetModuleHandle(nullptr); ofn.lpstrFilter = L"Font Information File\0*.fti\0\0"; ofn.lpstrFile = filePath.data(); ofn.nMaxFile = 2048; std::vector<wchar_t> curDir(2048); GetCurrentDirectory(2048, curDir.data()); ofn.lpstrInitialDir = curDir.data(); ofn.lpstrTitle = L"Select output location"; ofn.Flags |= OFN_PATHMUSTEXIST; ofn.lpstrDefExt = L"fti"; if(GetSaveFileName(&ofn) == FALSE) { return TRUE; } mOutFile = filePath.data(); saveToFile(); } } if(HIWORD(wParam) == BN_CLICKED) { if(LOWORD(wParam) == IDC_CP_ADD) { int32 index = ListBox_GetCurSel(GetDlgItem(mWindow, IDC_CP_AVAIL_LIST)); mCurrentBlock = mBlockVector[index]; RedrawWindow(GetDlgItem(mWindow, IDC_PREVIEW), nullptr, nullptr, RDW_INVALIDATE); ListBox_DeleteString(GetDlgItem(mWindow, IDC_CP_AVAIL_LIST), index); auto info = mBlockVector[index]; mBlockVector.erase(mBlockVector.begin() + index); mActiveBlocks.push_back(info); ListBox_AddString(GetDlgItem(mWindow, IDC_CP_USED), info.name->c_str()); } if(LOWORD(wParam) == IDC_FONT_SELECT) { LOGFONT logFont; CHOOSEFONT cf = { 0 }; cf.lStructSize = sizeof(CHOOSEFONT); cf.hwndOwner = mWindow; cf.hDC = nullptr; cf.lpLogFont = &logFont; cf.iPointSize = 120; BOOL res = ChooseFont(&cf); if(res == FALSE) { break; } HDC hDC = GetDC(nullptr); auto height = -MulDiv(logFont.lfHeight, GetDeviceCaps(hDC, LOGPIXELSY), 72); std::wstringstream fontDesc; fontDesc << logFont.lfFaceName << L", " << height << L" px, "; switch(logFont.lfWeight) { case FW_THIN: fontDesc << L"Thin"; break; case FW_EXTRALIGHT: fontDesc << L"Extra Light"; break; case FW_LIGHT: fontDesc << L"Light"; break; case FW_NORMAL: fontDesc << L"Regular"; break; case FW_MEDIUM: fontDesc << L"Medium"; break; case FW_SEMIBOLD: fontDesc << L"Semibold"; break; case FW_BOLD: fontDesc << L"Bold"; break; case FW_EXTRABOLD: fontDesc << L"Extra bold"; break; case FW_HEAVY: fontDesc << L"Heavy"; break; } Edit_SetText(GetDlgItem(mWindow, IDC_FONT_DESC), fontDesc.str().c_str()); delete mDefFont; mDefFont = new Font(hDC, &logFont); ReleaseDC(nullptr, hDC); mFontSize = height; RedrawWindow(GetDlgItem(mWindow, IDC_PREVIEW), nullptr, nullptr, RDW_INVALIDATE); } } } return TRUE; default: return FALSE; } return TRUE; }
void MainWindow::saveToFile() { std::ofstream outFile(mOutFile, std::ios::binary); std::stringstream out; uint32 signature = 'FNTI'; out.write((const char*)&signature, sizeof(uint32)); struct FNTIHeader { uint32 numPages; uint32 ofsPages; } header; header.numPages = mActiveBlocks.size(); header.ofsPages = sizeof(FNTIHeader) + sizeof(uint32); out.write((const char*)&header, sizeof(FNTIHeader)); struct FNTIBlockDesc { uint32 id; uint32 numChars; uint32 ofsChars; uint32 bmpWidth; uint32 bmpHeight; uint32 ofsBmp; wchar_t minChar; wchar_t maxChar; wchar_t pageName[64]; }; std::vector<FNTIBlockDesc> descriptions(mActiveBlocks.size()); uint32 counter = 0; for(auto& block : mActiveBlocks) { FNTIBlockDesc desc; memset(&desc, 0, sizeof(desc)); desc.id = block.id; desc.bmpWidth = 256; desc.bmpHeight = 256; desc.minChar = (wchar_t)block.minChar; desc.maxChar = (wchar_t)block.maxChar; wcsncpy_s(desc.pageName, block.name->c_str(), 64); desc.pageName[63] = L'\0'; out.write((const char*)&desc, sizeof(desc)); descriptions[counter++] = desc; } std::vector<Bitmap*> bitmaps(mActiveBlocks.size()); Bitmap* tmp = new Bitmap(mFontSize * 2, mFontSize); Graphics* gchar = Graphics::FromImage(tmp); gchar->SetTextRenderingHint(TextRenderingHintAntiAlias); for(uint32 i = 0; i < mActiveBlocks.size(); ++i) { auto& desc = descriptions[i]; desc.ofsChars = (uint32)out.tellp(); Bitmap* bmp = new Bitmap(256, 256); bitmaps[i] = bmp; Graphics* g = Graphics::FromImage(bmp); g->Clear(Color::Transparent); g->SetTextRenderingHint(TextRenderingHintAntiAlias); uint32 curW = 0, curH = 0; for(uint32 j = mActiveBlocks[i].minChar; j < mActiveBlocks[i].maxChar; ++j) { char c = (char)j; wchar_t wc = (wchar_t)j; RectF rcChar; g->MeasureString(&wc, 1, mDefFont, PointF(0, 0), &rcChar); float width = rcChar.Width; if(curW + width > bmp->GetWidth()) { curW = 0; curH += mFontSize + 3; } g->DrawString(&wc, 1, mDefFont, PointF((float)curW, (float)curH), mWhiteBrush); gchar->Clear(Color::Black); gchar->DrawString(&wc, 1, mDefFont, PointF(0, 0), mWhiteBrush); Color pxl, pxr; uint32 ofsl = 0, ofsr = 0; bool lfound = false, rfound = false; for(uint32 l = 0; l < mFontSize * 2; ++l) { for(uint32 h = 0; h < mFontSize; ++h) { uint32 r = (2 * mFontSize - 1) - l; if(lfound == false) { tmp->GetPixel(l, h, &pxl); if(pxl.GetRed() > 5) { lfound = true; ofsl = l; } } if(rfound == false) { tmp->GetPixel(r, h, &pxr); if(pxr.GetRed() > 5) { rfound = true; ofsr = r; } } if(lfound && rfound) { break; } } if(lfound && rfound) { break; } } if(lfound == false || rfound == false || (ofsl >= ofsr)) { continue; } uint16 chrWidth = ofsr - ofsl + 1; float txs = (curW + ofsl) / (float)bmp->GetWidth(); float txe = (curW + width - ofsr) / (float)bmp->GetWidth(); float tys = curH / (float)bmp->GetHeight(); float tye = (curH + mFontSize) / (float)bmp->GetHeight(); curW += (uint32)ceil(width) + 2; ++desc.numChars; out.write((const char*)&wc, sizeof(wchar_t)); out.write((const char*)&chrWidth, sizeof(uint16)); out.write((const char*)&txs, sizeof(float)); out.write((const char*)&txe, sizeof(float)); out.write((const char*)&tys, sizeof(float)); out.write((const char*)&tye, sizeof(float)); } delete g; } delete gchar; delete tmp; for(uint32 i = 0; i < mActiveBlocks.size(); ++i) { auto& desc = descriptions[i]; desc.ofsBmp = (uint32)out.tellp(); Bitmap* bmp = bitmaps[i]; BitmapData data; bmp->LockBits(&Rect(0, 0, bmp->GetWidth(), bmp->GetHeight()), 0, PixelFormat32bppARGB, &data); out.write((const char*)data.Scan0, bmp->GetWidth() * bmp->GetHeight()); bmp->UnlockBits(&data); delete bmp; } out.seekp(header.ofsPages, std::ios::beg); out.write((const char*)descriptions.data(), descriptions.size() * sizeof(FNTIBlockDesc)); out.seekp(0, std::ios::end); uint32 end = (uint32)out.tellp(); out.seekg(0, std::ios::beg); std::vector<char> content(end); out.read(content.data(), end); std::vector<char> compressed(end); Utils::ZDeflater defl; defl.begin(); uint32 outPos = 0; defl.update(content, compressed, outPos); compressed.resize(outPos); defl.end(); outFile.write((const char*)&end, sizeof(uint32)); outFile.write(compressed.data(), compressed.size()); outFile.close(); }