7216fbf3ffc72cb77bf509c0bffe719a1daa0ed5 braney Sun Sep 6 16:20:34 2020 -0700 first cut at using FreeType for font support diff --git src/lib/memgfx.c src/lib/memgfx.c index 9066015..66abe18 100644 --- src/lib/memgfx.c +++ src/lib/memgfx.c @@ -1,28 +1,29 @@ /* memgfx - routines for drawing on bitmaps in memory. * Currently limited to 256 color bitmaps. * * This file is copyright 2002 Jim Kent, but license is hereby * granted for all use - public, private or commercial. */ #include "common.h" #include "memgfx.h" #include "gemfont.h" #include "localmem.h" #include "vGfx.h" #include "vGfxPrivate.h" #include "colHash.h" +#include "freeType.h" Color multiply(Color src, Color new) { unsigned char rs = (src >> 0) & 0xff; unsigned char gs = (src >> 8) & 0xff; unsigned char bs = (src >> 16) & 0xff; unsigned char rn = (new >> 0) & 0xff; unsigned char gn = (new >> 8) & 0xff; unsigned char bn = (new >> 16) & 0xff; unsigned char ro = ((unsigned) rn * rs) / 255; unsigned char go = ((unsigned) gn * gs) / 255; unsigned char bo = ((unsigned) bn * bs) / 255; return MAKECOLOR_32(ro, go, bo); @@ -317,47 +318,30 @@ switch(mg->writeMode) { case MG_WRITE_MODE_NORMAL: { mgDrawBoxNormal(mg,x,y, width, height, color); } break; case MG_WRITE_MODE_MULTIPLY: { mgDrawBoxMultiply(mg,x,y, width, height, color); } break; } } - -INLINE void mixDot(struct memGfx *img, int x, int y, float frac, Color col) -/* Puts a single dot on the image, mixing it with what is already there - * based on the frac argument. */ -{ -if ((x < img->clipMinX) || (x >= img->clipMaxX) || (y < img->clipMinY) || (y >= img->clipMaxY)) - return; - -Color *pt = _mgPixAdr(img,x,y); -float invFrac = 1 - frac; - -int r = COLOR_32_RED(*pt) * invFrac + COLOR_32_RED(col) * frac; -int g = COLOR_32_GREEN(*pt) * invFrac + COLOR_32_GREEN(col) * frac; -int b = COLOR_32_BLUE(*pt) * invFrac + COLOR_32_BLUE(col) * frac; -mgPutDot(img,x,y,MAKECOLOR_32(r,g,b)); -} - #define fraction(X) (((double)(X))-(double)(int)(X)) #define invFraction(X) (1.0-fraction(X)) void mgAliasLine( struct memGfx *mg, int x1, int y1, int x2, int y2, Color color) /* Draw an antialiased line using the Wu algorithm. */ { double dx = (double)x2 - (double)x1; double dy = (double)y2 - (double)y1; // figure out what quadrant we're in if ( fabs(dx) > fabs(dy) ) { if ( x2 < x1 ) { @@ -744,31 +728,39 @@ { inByte = *in++; inBit = 0x80; } } inLine += bitDataRowBytes; outLine += _mgBpr(dest); } } void mgText(struct memGfx *mg, int x, int y, Color color, MgFont *font, char *text) /* Draw a line of text with upper left corner x,y. */ { +switch (mg->fontMethod) + { + case FONT_METHOD_GEM: gfText(mg, font, text, x, y, color, mgTextBlit, MG_WHITE); + break; + case FONT_METHOD_FREETYPE: + ftText(mg, x, y, color, font, text); + break; + } } void mgTextCentered(struct memGfx *mg, int x, int y, int width, int height, Color color, MgFont *font, char *text) /* Draw a line of text centered in box defined by x/y/width/height */ { int fWidth, fHeight; int xoff, yoff; fWidth = mgFontStringWidth(font, text); fHeight = mgFontPixelHeight(font); xoff = x + (width - fWidth)/2; yoff = y + (height - fHeight)/2; if (font == mgSmallFont()) { xoff += 1; @@ -804,45 +796,62 @@ int mgGetFontPixelHeight(struct memGfx *mg, MgFont *font) /* How high in pixels is font? */ { return mgFontPixelHeight(font); } int mgFontLineHeight(MgFont *font) /* How many pixels to next line ideally? */ { return font_line_height(font); } int mgFontWidth(MgFont *font, char *chars, int charCount) /* How wide are a couple of letters? */ { -return fnstring_width(font, (unsigned char *)chars, charCount); +/* +switch (mg->fontMethod) + { + case FONT_METHOD_GEM: + */ + return 1.00 * fnstring_width(font, (unsigned char *)chars, charCount); + //case FONT_METHOD_FREETYPE: + //return ftWidth(font, (unsigned char *)chars, charCount); + // } } int mgFontStringWidth(MgFont *font, char *string) /* How wide is a string? */ { return mgFontWidth(font, string, strlen(string)); } int mgGetFontStringWidth(struct memGfx *mg, MgFont *font, char *string) /* How wide is a string? */ { return mgFontStringWidth(font, string); } +void mgSetFontMethod(struct memGfx *mg, unsigned int method) +/* Which font drawing method shoud we use. */ +{ +mg->fontMethod = method; + +if (method == FONT_METHOD_FREETYPE) + ftInitialize(); +} + int mgFontCharWidth(MgFont *font, char c) /* How wide is a character? */ { return mgFontWidth(font, &c, 1); } char *mgFontSizeBackwardsCompatible(char *size) /* Given "size" argument that may be in old tiny/small/medium/big/huge format, * return it in new numerical string format. Do NOT free the return string*/ { if (isdigit(size[0])) return size; else if (sameWord(size, "tiny")) return "6"; else if (sameWord(size, "small")) @@ -1007,30 +1016,31 @@ vg->findColorIx = (vg_findColorIx)mgFindColor; vg->colorIxToRgb = (vg_colorIxToRgb)mgColorIxToRgb; vg->setWriteMode = (vg_setWriteMode)mgSetWriteMode; vg->setClip = (vg_setClip)mgSetClip; vg->unclip = (vg_unclip)mgUnclip; vg->verticalSmear = (vg_verticalSmear)mgVerticalSmear; vg->fillUnder = (vg_fillUnder)mgFillUnder; vg->drawPoly = (vg_drawPoly)mgDrawPoly; vg->circle = (vg_circle)mgCircle; vg->ellipse = (vg_ellipse)mgEllipse; vg->curve = (vg_curve)mgCurve; vg->setHint = (vg_setHint)mgSetHint; vg->getHint = (vg_getHint)mgGetHint; vg->getFontPixelHeight = (vg_getFontPixelHeight)mgGetFontPixelHeight; vg->getFontStringWidth = (vg_getFontStringWidth)mgGetFontStringWidth; +vg->setFontMethod = (vg_setFontMethod)mgSetFontMethod; } struct hslColor mgRgbToHsl(struct rgbColor rgb) /* Convert RGB to HSL colorspace (see http://en.wikipedia.org/wiki/HSL_and_HSV) * In HSL, Hue is the color in the range [0,360) with 0=red 120=green 240=blue, * Saturation goes from a shade of grey (0) to fully saturated color (1000), and * Lightness goes from black (0) through the hue (500) to white (1000). */ { unsigned char rgbMax = max3(rgb.r, rgb.g, rgb.b); unsigned char rgbMin = min3(rgb.r, rgb.g, rgb.b); unsigned char delta = rgbMax - rgbMin; unsigned short minMax = rgbMax + rgbMin; int divisor; struct hslColor hsl = { 0.0, 0, (1000*minMax+255)/(2*255) }; // round up