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