aboutsummaryrefslogtreecommitdiff
path: root/graphics/fonts/macfont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/fonts/macfont.cpp')
-rw-r--r--graphics/fonts/macfont.cpp205
1 files changed, 193 insertions, 12 deletions
diff --git a/graphics/fonts/macfont.cpp b/graphics/fonts/macfont.cpp
index 4264f64649..a32fac710f 100644
--- a/graphics/fonts/macfont.cpp
+++ b/graphics/fonts/macfont.cpp
@@ -25,6 +25,8 @@
#include "graphics/managed_surface.h"
#include "graphics/fonts/macfont.h"
+#define DEBUGSCALING 0
+
namespace Graphics {
enum {
@@ -393,7 +395,14 @@ int MacFONTFont::getKerningOffset(uint32 left, uint32 right) const {
return 0;
}
-MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize) {
+#if DEBUGSCALING
+bool dododo;
+#endif
+
+static void magnifyGray(Surface *src, int *dstGray, int width, int height, float scale);
+static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height);
+
+MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize, bool bold, bool italic) {
if (!src) {
warning("Empty font reference in scale font");
return NULL;
@@ -404,6 +413,12 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize) {
return NULL;
}
+ Graphics::Surface srcSurf;
+ srcSurf.create(MAX(src->getFontSize() * 2, newSize * 2), MAX(src->getFontSize() * 2, newSize * 2),
+ PixelFormat::createFormatCLUT8());
+ int dstGraySize = newSize * 2 * newSize;
+ int *dstGray = (int *)malloc(dstGraySize * sizeof(int));
+
float scale = (float)newSize / (float)src->getFontSize();
MacFONTdata data;
@@ -427,7 +442,7 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize) {
data._glyphs.resize(src->_data._glyphs.size());
- // Dtermine width of the bit image table
+ // Determine width of the bit image table
int newBitmapWidth = 0;
for (uint i = 0; i < src->_data._glyphs.size() + 1; i++) {
MacGlyph *glyph = (i == src->_data._glyphs.size()) ? &data._defaultChar : &data._glyphs[i];
@@ -435,10 +450,11 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize) {
glyph->width = (int)((float)srcglyph->width * scale);
glyph->kerningOffset = (int)((float)srcglyph->kerningOffset * scale);
- glyph->bitmapWidth = (int)((float)srcglyph->bitmapWidth * scale);
+ glyph->bitmapWidth = glyph->width; //(int)((float)srcglyph->bitmapWidth * scale);
glyph->bitmapOffset = newBitmapWidth;
- newBitmapWidth += (glyph->bitmapWidth + 7) & ~0x7;
+ // Align width to a byte
+ newBitmapWidth += (glyph->bitmapWidth + 7 + 2) & ~0x7; // Add 2 pixels for italic and bold
}
data._rowWords = newBitmapWidth;
@@ -446,51 +462,216 @@ MacFONTFont *MacFONTFont::scaleFont(const MacFONTFont *src, int newSize) {
uint bitImageSize = data._rowWords * data._fRectHeight;
data._bitImage = new byte[bitImageSize];
- int srcPitch = src->_data._rowWords;
int dstPitch = data._rowWords;
for (uint i = 0; i < src->_data._glyphs.size() + 1; i++) {
const MacGlyph *srcglyph = (i == src->_data._glyphs.size()) ? &src->_data._defaultChar : &src->_data._glyphs[i];
+
+ int grayLevel = src->_data._fRectHeight * srcglyph->width / 4;
+
+#if DEBUGSCALING
+ int ccc = 'c';
+ dododo = i == ccc;
+#endif
+
+ srcSurf.fillRect(Common::Rect(srcSurf.w, srcSurf.h), 0);
+ src->drawChar(&srcSurf, i + src->_data._firstChar, 0, 0, 1);
+ memset(dstGray, 0, dstGraySize * sizeof(int));
+ magnifyGray(&srcSurf, dstGray, srcglyph->width, src->_data._fRectHeight, scale);
+
MacGlyph *glyph = (i == src->_data._glyphs.size()) ? &data._defaultChar : &data._glyphs[i];
+ int *grayPtr = dstGray;
+
+ for (int y = 0; y < data._fRectHeight; y++) {
+ byte *dst = (byte *)srcSurf.getBasePtr(0, y);
+
+ for (int x = 0; x < glyph->width; x++, grayPtr++, dst++) {
+#if DEBUGSCALING
+ if (i == ccc) {
+ if (*grayPtr)
+ debugN(1, "%3d ", *grayPtr);
+ else
+ debugN(1, " ");
+ }
+#endif
+ if (*grayPtr > grayLevel)
+ *dst = 1;
+ else
+ *dst = 0;
+ }
+#if DEBUGSCALING
+ if (i == ccc)
+ debug(1, "");
+#endif
+ }
+
+ if (bold) {
+ memset(dstGray, 0, dstGraySize * sizeof(int));
+ makeBold(&srcSurf, dstGray, glyph, data._fRectHeight);
+
+ for (uint16 y = 0; y < data._fRectHeight; y++) {
+ int *srcPtr = &dstGray[y * glyph->width];
+ byte *dstPtr = (byte *)srcSurf.getBasePtr(0, y);
+
+ for (uint16 x = 0; x < glyph->width; x++, srcPtr++, dstPtr++) {
+ if (*srcPtr)
+ *dstPtr = 1;
+
+#if DEBUGSCALING
+ if (i == ccc)
+ debugN("%c", *srcPtr ? '@' : '.');
+#endif
+ }
+
+#if DEBUGSCALING
+ if (i == ccc)
+ debugN("\n");
+#endif
+ }
+ }
+
byte *ptr = &data._bitImage[glyph->bitmapOffset / 8];
for (int y = 0; y < data._fRectHeight; y++) {
- const byte *srcd = (const byte *)&src->_data._bitImage[((int)((float)y / scale)) * srcPitch];
byte *dst = ptr;
+ byte *srcPtr = (byte *)srcSurf.getBasePtr(0, y);
byte b = 0;
- for (int x = 0; x < glyph->width; x++) {
- int sx = (int)((float)x / scale) + srcglyph->bitmapOffset;
+ for (int x = 0; x < glyph->width; x++, srcPtr++) {
+ b <<= 1;
- if (srcd[sx / 8] & (0x80 >> (sx % 8)))
+ if (*srcPtr == 1)
b |= 1;
- if (!(x % 8) && x) {
+ if (x % 8 == 7) {
*dst++ = b;
b = 0;
}
+ }
- b <<= 1;
+#if DEBUGSCALING
+ if (i == ccc) {
+ debugN(1, "--> %d ", grayLevel);
+
+ grayPtr = &dstGray[y * glyph->width];
+ for (int x = 0; x < glyph->width; x++, grayPtr++)
+ debugN("%c", *grayPtr > grayLevel ? '#' : '.');
}
+#endif
if (((glyph->width - 1) % 8)) {
+#if DEBUGSCALING
+ if (i == ccc)
+ debugN(" --- %02x (w: %d bw: %d << %d)", b, glyph->width, glyph->bitmapWidth, 7 - ((glyph->width - 1) % 8));
+#endif
+
b <<= 7 - ((glyph->width - 1) % 8);
*dst = b;
+
+#if DEBUGSCALING
+ if (i == ccc)
+ debugN(" --- %02x ", b);
+#endif
+ }
+
+#if DEBUGSCALING
+ if (i == ccc) {
+ byte *srcRow = data._bitImage + y * data._rowWords;
+
+ for (uint16 x = 0; x < glyph->bitmapWidth; x++) {
+ uint16 bitmapOffset = glyph->bitmapOffset + x;
+
+ debugN("%c", srcRow[bitmapOffset / 8] & (1 << (7 - (bitmapOffset % 8))) ? '*' : '.');
+ }
+
+ debugN("\n");
}
+#endif
ptr += dstPitch;
}
}
+ srcSurf.free();
+ free(dstGray);
+
return new MacFONTFont(data);
}
+#define howmany(x, y) (((x)+((y)-1))/(y))
+
+static void countupScore(int *dstGray, int x, int y, int bbw, int bbh, float scale) {
+ int newbbw = bbw * scale;
+ int newbbh = bbh * scale;
+ int x_ = x * newbbw;
+ int y_ = y * newbbh;
+ int x1 = x_ + newbbw;
+ int y1 = y_ + newbbh;
+
+ int newxbegin = x_ / bbw;
+ int newybegin = y_ / bbh;
+ int newxend = howmany(x1, bbw);
+ int newyend = howmany(y1, bbh);
+
+ for (int newy = newybegin; newy < newyend; newy++) {
+ for (int newx = newxbegin; newx < newxend; newx++) {
+ int newX = newx * bbw;
+ int newY = newy * bbh;
+ int newX1 = newX + bbw;
+ int newY1 = newY + bbh;
+ dstGray[newy * newbbw + newx] += (MIN(x1, newX1) - MAX(x_, newX)) *
+ (MIN(y1, newY1) - MAX(y_, newY));
+ }
+ }
+}
+
+static void magnifyGray(Surface *src, int *dstGray, int width, int height, float scale) {
+ for (uint16 y = 0; y < height; y++) {
+ for (uint16 x = 0; x < width; x++) {
+ if (*((byte *)src->getBasePtr(x, y)) == 1)
+ countupScore(dstGray, x, y, width, height, scale);
+#if DEBUGSCALING
+ if (dododo)
+ debugN("%c", *((byte *)src->getBasePtr(x, y)) == 1 ? '*' : ' ');
+#endif
+ }
+
+#if DEBUGSCALING
+ if (dododo)
+ debugN("\n");
+#endif
+ }
+}
+
+static void makeBold(Surface *src, int *dstGray, MacGlyph *glyph, int height) {
+ glyph->width++;
+
+ for (uint16 y = 0; y < height; y++) {
+ byte *srcPtr = (byte *)src->getBasePtr(0, y);
+ int *dst = &dstGray[y * glyph->width];
+
+ for (uint16 x = 0; x < glyph->width; x++, srcPtr++, dst++) {
+ bool left = x ? *(srcPtr - 1) == 1 : false;
+ bool center = *srcPtr == 1;
+ bool right = x > glyph->width - 1 ? false : *(srcPtr + 1) == 1;
+
+ bool edge, bold, res;
+
+ bold = center || left;
+ edge = !center && right;
+ res = (bold && !edge);
+
+ *dst = res ? 1 : 0;
+ }
+ }
+}
+
void MacFONTFont::testBlit(const MacFONTFont *src, ManagedSurface *dst, int color, int x0, int y0, int width) {
for (int y = 0; y < src->_data._fRectHeight; y++) {
byte *srcRow = src->_data._bitImage + y * src->_data._rowWords;
for (int x = 0; x < width; x++) {
- uint16 bitmapOffset = x;
+ uint16 bitmapOffset = x + 64;
if (srcRow[bitmapOffset / 8] & (1 << (7 - (bitmapOffset % 8)))) {
if (dst->format.bytesPerPixel == 1)