storing something in a compact grid

Started by
3 comments, last by outRider 22 years, 8 months ago
Forgive the vague subject, I couldn''t find the words to accurately describe my question that space. What I''m trying to do is draw a GDI font onto a GDI bitmap to use elsewhere. Lets say I want to draw 224 characters onto a bitmap, I can draw them all in a row and have a bitmap that''s 2042* 8 or something like that. What I want to do is find a way to make the bitmap as square as possible by putting them in rows/columns. In the above case the best way would be to have a 14*16 grid or a 16*14, but what if I have some other value, like say 96 characters, or 256, or 64, or 15, or 77? Any help anyone can offer would be appreciated. ------------ - outRider -
Advertisement
DrawText( HDC hDC, // device context hnd
LPCTSTR lpString, // Pointer to string to draw
int nCount, // string length, in characters
LPRECT lpRect, // ptr to bounding RECT
UINT uFormat); // flags
// DT_LEFT formats to left
// Look in Win32 doc for more flags

// Both return the old color, so you can set it back when done.
COLORREF SetTextColor(HDC hDC, COLORREF Color);
COLORREF SetBkColor(HDC hDC, COLORREF Color);

// to get a color
COLORREF RGB(Red, Green, Blue)
(http://www.ironfroggy.com/)(http://www.ironfroggy.com/pinch)
Uh...

To reply to the original question, I assume that your characters are square. Otherwise, you have more math on your hands.

You are given the total number of characters (C) and would like to place them in a grid as close to square as possible, with M rows of N columns each.

this is a pseudo-algorithm to do that:

let M=ceil(sqrt(C))
repeat until M is a factor of C (C/M has no remainder)
M--
now, N=C/M

What this does is assume that M and N are equal so that MM=C. If this doesn''t work out quite right, we will use this as a starting point and work down until we hit a number that works.

This will not work if C is a prime number (in which case, you could increase C by one and try again).
MartinJ,

They aren''t necessarily square, the height is whatever I pass to CreateFont, but the width is different for each character in the font face. Here''s what I have so far:

hFont = CreateFont(-byHeight, 0, 0, 0, FW_NORMAL, false, false, false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE | DEFAULT_PITCH, pszFontname);	SelectObject(hDC, hFont);	GetTextMetrics(hDC, &tm);	rVal = FindOptimumGrid(byEndChar - (byStartChar - 1));	iGridWidth = LOBYTE(rVal) * tm.tmMaxCharWidth;	iGridHeight = HIBYTE(rVal) * tm.tmHeight;	BmpInfo.bmiHeader.biWidth = iGridWidth;	BmpInfo.bmiHeader.biHeight = iGridHeight;	hBmp = CreateDIBSection(hDC, &BmpInfo, DIB_RGB_COLORS, NULL, NULL, NULL);	SelectObject(hDC, hBmp);	for (y = 0; y < iGridHeight; y += tm.tmHeight)	{		for (x = 0; x < iGridWidth; x += tm.tmMaxCharWidth)		{			TextOut(hDC, x, y, &byCurrentChar, 1);			byCurrentChar++;		}	}short FindOptimumGrid(BYTE nChars){	while (byFactor1 < byFactor2)	{		if (nChars % byCurrentDivisor == 0)		{			byFactor1 = byCurrentDivisor;			byFactor2 = nChars / byCurrentDivisor;		}		byCurrentDivisor++;	}	byOptimumGrid = byFactor1;	byOptimumGrid += byFactor2 << 8;	return iOptimumGrid;}


That works fine, but if the amount of characters wont fit equally on the grid it doesn''t work, just because as CurrentDivisor increases, depending on the amount of characters, nChars % CurrentDivisor wont end up being zero... I''m not sure how to deal with that really.

Anyway, MartinJ, M=ceil(sqrt(C)), what is ceil()?

------------
- outRider -
ceil() should bring back an integer, always rounding up. Unless I''ve been sniffing the glue on the back of the post-it notes too much. It could be named something else... that''s just what I thought it was called. I just used that to get an integer number (you really can''t have 1.354 cells across).

Since each character has a different width, I can''t think of anything other than brute force.

This topic is closed to new replies.

Advertisement