mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
font_windows.c: don't crash if no memory for bitmap [Peter Ferrie]
more graceful exit will occur when next malloc() fails, and condition might be temporary
This commit is contained in:
parent
490ed5ce9b
commit
9cf8308096
@ -169,90 +169,95 @@ bool osd_font_windows::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT
|
|||||||
// create a DIB to render to
|
// create a DIB to render to
|
||||||
BYTE *bits;
|
BYTE *bits;
|
||||||
HBITMAP dib = CreateDIBSection(dummyDC, &info, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits), NULL, 0);
|
HBITMAP dib = CreateDIBSection(dummyDC, &info, DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits), NULL, 0);
|
||||||
HGDIOBJ oldbitmap = SelectObject(dummyDC, dib);
|
|
||||||
|
|
||||||
// clear the bitmap
|
if (dib)
|
||||||
int rowbytes = bmwidth / 8;
|
|
||||||
memset(bits, 0, rowbytes * bmheight);
|
|
||||||
|
|
||||||
// now draw the character
|
|
||||||
WCHAR tempchar = chnum;
|
|
||||||
SetTextColor(dummyDC, RGB(0xff, 0xff, 0xff));
|
|
||||||
SetBkColor(dummyDC, RGB(0x00, 0x00, 0x00));
|
|
||||||
ExtTextOutW(dummyDC, 50 + abc.abcA, 50, ETO_OPAQUE, NULL, &tempchar, 1, NULL);
|
|
||||||
|
|
||||||
// characters are expected to be full-height
|
|
||||||
rectangle actbounds;
|
|
||||||
actbounds.min_y = 50;
|
|
||||||
actbounds.max_y = 50 + metrics.tmHeight - 1;
|
|
||||||
|
|
||||||
// determine the actual left of the character
|
|
||||||
for (actbounds.min_x = 0; actbounds.min_x < rowbytes; actbounds.min_x++)
|
|
||||||
{
|
{
|
||||||
BYTE *offs = bits + actbounds.min_x;
|
HGDIOBJ oldbitmap = SelectObject(dummyDC, dib);
|
||||||
UINT8 summary = 0;
|
|
||||||
for (int y = 0; y < bmheight; y++)
|
|
||||||
summary |= offs[y * rowbytes];
|
|
||||||
if (summary != 0)
|
|
||||||
{
|
|
||||||
actbounds.min_x *= 8;
|
|
||||||
if (!(summary & 0x80)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xc0)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xe0)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xf0)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xf8)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xfc)) actbounds.min_x++;
|
|
||||||
if (!(summary & 0xfe)) actbounds.min_x++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the actual right of the character
|
// clear the bitmap
|
||||||
for (actbounds.max_x = rowbytes - 1; actbounds.max_x >= 0; actbounds.max_x--)
|
int rowbytes = bmwidth / 8;
|
||||||
{
|
memset(bits, 0, rowbytes * bmheight);
|
||||||
BYTE *offs = bits + actbounds.max_x;
|
|
||||||
UINT8 summary = 0;
|
|
||||||
for (int y = 0; y < bmheight; y++)
|
|
||||||
summary |= offs[y * rowbytes];
|
|
||||||
if (summary != 0)
|
|
||||||
{
|
|
||||||
actbounds.max_x *= 8;
|
|
||||||
if (summary & 0x7f) actbounds.max_x++;
|
|
||||||
if (summary & 0x3f) actbounds.max_x++;
|
|
||||||
if (summary & 0x1f) actbounds.max_x++;
|
|
||||||
if (summary & 0x0f) actbounds.max_x++;
|
|
||||||
if (summary & 0x07) actbounds.max_x++;
|
|
||||||
if (summary & 0x03) actbounds.max_x++;
|
|
||||||
if (summary & 0x01) actbounds.max_x++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate a new bitmap
|
// now draw the character
|
||||||
if (actbounds.max_x >= actbounds.min_x && actbounds.max_y >= actbounds.min_y)
|
WCHAR tempchar = chnum;
|
||||||
{
|
SetTextColor(dummyDC, RGB(0xff, 0xff, 0xff));
|
||||||
bitmap.allocate(actbounds.max_x + 1 - actbounds.min_x, actbounds.max_y + 1 - actbounds.min_y);
|
SetBkColor(dummyDC, RGB(0x00, 0x00, 0x00));
|
||||||
|
ExtTextOutW(dummyDC, 50 + abc.abcA, 50, ETO_OPAQUE, NULL, &tempchar, 1, NULL);
|
||||||
|
|
||||||
// copy the bits into it
|
// characters are expected to be full-height
|
||||||
for (int y = 0; y < bitmap.height(); y++)
|
rectangle actbounds;
|
||||||
|
actbounds.min_y = 50;
|
||||||
|
actbounds.max_y = 50 + metrics.tmHeight - 1;
|
||||||
|
|
||||||
|
// determine the actual left of the character
|
||||||
|
for (actbounds.min_x = 0; actbounds.min_x < rowbytes; actbounds.min_x++)
|
||||||
{
|
{
|
||||||
UINT32 *dstrow = &bitmap.pix32(y);
|
BYTE *offs = bits + actbounds.min_x;
|
||||||
UINT8 *srcrow = &bits[(y + actbounds.min_y) * rowbytes];
|
UINT8 summary = 0;
|
||||||
for (int x = 0; x < bitmap.width(); x++)
|
for (int y = 0; y < bmheight; y++)
|
||||||
|
summary |= offs[y * rowbytes];
|
||||||
|
if (summary != 0)
|
||||||
{
|
{
|
||||||
int effx = x + actbounds.min_x;
|
actbounds.min_x *= 8;
|
||||||
dstrow[x] = ((srcrow[effx / 8] << (effx % 8)) & 0x80) ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff);
|
if (!(summary & 0x80)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xc0)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xe0)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xf0)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xf8)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xfc)) actbounds.min_x++;
|
||||||
|
if (!(summary & 0xfe)) actbounds.min_x++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the final offset values
|
// determine the actual right of the character
|
||||||
xoffs = actbounds.min_x - (50 + abc.abcA);
|
for (actbounds.max_x = rowbytes - 1; actbounds.max_x >= 0; actbounds.max_x--)
|
||||||
yoffs = actbounds.max_y - (50 + metrics.tmAscent);
|
{
|
||||||
|
BYTE *offs = bits + actbounds.max_x;
|
||||||
|
UINT8 summary = 0;
|
||||||
|
for (int y = 0; y < bmheight; y++)
|
||||||
|
summary |= offs[y * rowbytes];
|
||||||
|
if (summary != 0)
|
||||||
|
{
|
||||||
|
actbounds.max_x *= 8;
|
||||||
|
if (summary & 0x7f) actbounds.max_x++;
|
||||||
|
if (summary & 0x3f) actbounds.max_x++;
|
||||||
|
if (summary & 0x1f) actbounds.max_x++;
|
||||||
|
if (summary & 0x0f) actbounds.max_x++;
|
||||||
|
if (summary & 0x07) actbounds.max_x++;
|
||||||
|
if (summary & 0x03) actbounds.max_x++;
|
||||||
|
if (summary & 0x01) actbounds.max_x++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate a new bitmap
|
||||||
|
if (actbounds.max_x >= actbounds.min_x && actbounds.max_y >= actbounds.min_y)
|
||||||
|
{
|
||||||
|
bitmap.allocate(actbounds.max_x + 1 - actbounds.min_x, actbounds.max_y + 1 - actbounds.min_y);
|
||||||
|
|
||||||
|
// copy the bits into it
|
||||||
|
for (int y = 0; y < bitmap.height(); y++)
|
||||||
|
{
|
||||||
|
UINT32 *dstrow = &bitmap.pix32(y);
|
||||||
|
UINT8 *srcrow = &bits[(y + actbounds.min_y) * rowbytes];
|
||||||
|
for (int x = 0; x < bitmap.width(); x++)
|
||||||
|
{
|
||||||
|
int effx = x + actbounds.min_x;
|
||||||
|
dstrow[x] = ((srcrow[effx / 8] << (effx % 8)) & 0x80) ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the final offset values
|
||||||
|
xoffs = actbounds.min_x - (50 + abc.abcA);
|
||||||
|
yoffs = actbounds.max_y - (50 + metrics.tmAscent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// de-select the font and release the DC
|
||||||
|
SelectObject(dummyDC, oldbitmap);
|
||||||
|
DeleteObject(dib);
|
||||||
}
|
}
|
||||||
|
|
||||||
// de-select the font and release the DC
|
|
||||||
SelectObject(dummyDC, oldbitmap);
|
|
||||||
DeleteObject(dib);
|
|
||||||
SelectObject(dummyDC, oldfont);
|
SelectObject(dummyDC, oldfont);
|
||||||
DeleteDC(dummyDC);
|
DeleteDC(dummyDC);
|
||||||
return bitmap.valid();
|
return bitmap.valid();
|
||||||
|
Loading…
Reference in New Issue
Block a user