SUMO - Simulation of Urban MObility
polyfonts.c
Go to the documentation of this file.
00001 /*
00002   Polyfonts is a polygon font drawing library for use with SDL. Any
00003   TTF font can be converted for use with this library. Contact the
00004   author for details.
00005 
00006   Copyright (C) 2003 Bob Pendleton
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Lesser General Public License
00010   as published by the Free Software Foundation; either version 2.1
00011   of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016   Lesser General Public License for more details.
00017 
00018   You should have received a copy of the GNU Lesser General Public
00019   License along with this library; if not, write to the Free
00020   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00021   02111-1307 USA
00022 
00023   If you do not wish to comply with the terms of the LGPL please
00024   contact the author as other terms are available for a fee.
00025 
00026   Bob Pendleton
00027   Bob@Pendleton.com
00028 */
00029 
00030 // ===========================================================================
00031 // included modules
00032 // ===========================================================================
00033 #ifdef _MSC_VER
00034 #include <windows_config.h>
00035 #else
00036 #include <config.h>
00037 #endif
00038 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <math.h>
00042 #include <string.h>
00043 
00044 #ifdef _WIN32
00045 #include <windows.h>
00046 #endif
00047 
00048 #include <GL/gl.h>
00049 
00050 //#include "SDL.h"
00051 //#include "sgl.h"
00052 
00053 #include "polyfonts.h"
00054 
00055 /*-----------------------------------------------*/
00056 
00057 #define PI   (3.1415926535897932384626433)
00058 #define RtoD (180.0/PI)
00059 #define DtoR (PI/180.0)
00060 
00061 #define max(a,b) (((a) > (b)) ? (a) : (b))
00062 #define min(a,b) (((a) < (b)) ? (a) : (b))
00063 #define abs(a) (((a)<0) ? -(a) : (a))
00064 #define sign(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
00065 
00066 /*-----------------------------------------------*/
00067 /*
00068   The following code sets the default compiled in
00069   font. You can change the default font by
00070   including a different font and changing the
00071   declaration of the two variables. Or, you can
00072   set them both to NULL if you don't want a
00073   default font.
00074 */
00075 
00076 // changes for SUMO begin
00077 #include "pfPSansBold16.h"
00078 
00079 static pffont *pfCurrentFont = &pfPSansBold16;
00080 static pffont *pfDefaultFont = &pfPSansBold16;
00081 
00082 
00083 /* =========================================================================
00084  * compiler pragmas
00085  * ======================================================================= */
00086 #pragma warning(disable: 4244) // !!! should be replaced by a stronger type binding
00087 
00088 
00089 // changes for SUMO end
00090 
00091 /*
00092 static pffont *pfCurrentFont = NULL;
00093 static pffont *pfDefaultFont = NULL;
00094 */
00095 
00096 /*-----------------------------------------------*/
00097 
00098 static SUMOReal pfScaleX = 20.0;
00099 static SUMOReal pfScaleY = 20.0;
00100 
00101 static SUMOReal pfTextX = 0.0;
00102 static SUMOReal pfTextY = 0.0;
00103 
00104 static SUMOReal pfTextSkew = 0.0;
00105 static int pfTextWeight = 1;
00106 
00107 typedef struct
00108 {
00109   SUMOReal x, y;
00110 } vertex;
00111 
00112 vertex weightOffset[] = {
00113   {0.0, 0.0},
00114   {0.0, 1.0},
00115   {1.0, 1.0},
00116   {1.0, 0.0},
00117   /*-------*/
00118   {0.0, 2.0},
00119   {1.0, 2.0},
00120   {2.0, 2.0},
00121   {1.0, 2.0},
00122   {0.0, 2.0},
00123 };
00124 
00125 #define numWeights (sizeof(weightOffset) / sizeof(vertex))
00126 
00127 static SUMOReal pfTextSin = 0.0;
00128 static SUMOReal pfTextCos = 1.0;
00129 
00130 static int pfCenter = 0;
00131 
00132 #define unfix(value) ((SUMOReal)(value)) / ((SUMOReal)pfFixScale)
00133 
00134 /*-----------------------------------------------*/
00135 
00136 static pfglyph *pfGetGlyph(wchar_t c);
00137 static SUMOReal getCharAdvance(wchar_t c);
00138 
00139 /*-----------------------------------------------*/
00140 
00141 static SUMOReal pfSkew(SUMOReal x, SUMOReal y)
00142 {
00143   return x + (pfTextSkew * y);
00144 }
00145 
00146 /*-----------------------------------------------*/
00147 
00148 int pfSetFont(pffont *f)
00149 {
00150   if (NULL != f)
00151   {
00152     pfCurrentFont = f;
00153 
00154     return 0;
00155   }
00156 
00157   return -1;
00158 }
00159 
00160 /*-----------------------------------------------*/
00161 
00162 typedef struct
00163 {
00164   char *name;
00165   int value;
00166 } nameValue;
00167 
00168 static nameValue glPrims[] =
00169   {
00170     {"GL_POINTS",         GL_POINTS},
00171     {"GL_LINES",          GL_LINES},
00172     {"GL_LINE_LOOP",      GL_LINE_LOOP},
00173     {"GL_LINE_STRIP",     GL_LINE_STRIP},
00174     {"GL_TRIANGLES",      GL_TRIANGLES},
00175     {"GL_TRIANGLE_STRIP", GL_TRIANGLE_STRIP},
00176     {"GL_TRIANGLE_FAN",   GL_TRIANGLE_FAN},
00177     {"GL_QUADS",          GL_QUADS},
00178     {"GL_QUAD_STRIP",     GL_QUAD_STRIP},
00179     {"GL_POLYGON",        GL_POLYGON},
00180   };
00181 
00182 /*-----------------------------------------------*/
00183 
00184 static int lookupGlOp(char *op)
00185 {
00186   int i;
00187 
00188   for (i = 0; i < (sizeof(glPrims) / sizeof(nameValue)); i++)
00189   {
00190     if (0 == strcmp(glPrims[i].name, op))
00191     {
00192       return i;
00193     }
00194   }
00195 
00196   return -1;
00197 }
00198 
00199 /*-----------------------------------------------*/
00200 
00201 static void validate(pffont *font)
00202 {
00203   int i;
00204 
00205   pfglyph *glyph = NULL;
00206 
00207   if (NULL == font)
00208   {
00209     printf("font is NULL\n");
00210   }
00211 
00212   if (NULL == font->name)
00213   {
00214     printf("fontname is NULL\n");
00215   }
00216 
00217   printf("fontinfo = %s %f, %f, %f, %f, %d %p\n",
00218          font->name,
00219          font->minx, font->miny,
00220          font->maxx, font->maxy,
00221          font->numglyphs,
00222          font->glyphs);
00223 
00224   glyph = font->glyphs;
00225   if (NULL == glyph)
00226   {
00227     printf("glyph point is NULL\n");
00228   }
00229 
00230   printf("NumGlyphs = %d\n", font->numglyphs);
00231 
00232   for (i = 0; i < font->numglyphs; i++)
00233   {
00234     if (NULL == glyph[i].segments)
00235     {
00236       printf("glyph[%d].segments = NULL\n", i);
00237     }
00238 
00239     printf("glyph[%d] = %f, %f, %f, %f, %f, %hu, %hu %p\n",
00240            i,
00241            glyph[i].minx, glyph[i].miny,
00242            glyph[i].maxx, glyph[i].maxy,
00243            glyph[i].advance,
00244            glyph[i].glyph,
00245            glyph[i].numsegments,
00246            glyph[i].segments);
00247   }
00248 }
00249 
00250 /*-----------------------------------------------*/
00251 
00252 void pfUnloadFont(pffont *font)
00253 {
00254   int i;
00255 
00256   pfglyph *glyphs = NULL;
00257 
00258   if (NULL == font)
00259   {
00260     return;
00261   }
00262 
00263   if (pfDefaultFont == font)
00264   {
00265     return;
00266   }
00267 
00268   if (1 != font->loaded)
00269   {
00270     return;
00271   }
00272 
00273   if (NULL == font->name)
00274   {
00275     return;
00276   }
00277   free(font->name);
00278 
00279   if (NULL == font->glyphs)
00280   {
00281     return;
00282   }
00283 
00284   glyphs = font->glyphs;
00285   for (i = 0; i < font->numglyphs; i++)
00286   {
00287     if (NULL != glyphs[i].segments)
00288     {
00289       free(glyphs[i].segments);
00290     }
00291   }
00292 
00293   free(font->glyphs);
00294 
00295   free(font);
00296 }
00297 
00298 /*-----------------------------------------------*/
00299 
00300 #ifdef POLYFONTS_WANTS_IO
00301 pffont *pfLoadFont(char *fileName)
00302 {
00303   FILE *f = NULL;
00304   char buf[1024];
00305 
00306   SUMOReal version = 0;
00307   int glyphcount = 0;
00308   char *fontname = NULL;
00309   pffont *fontinfo = NULL;
00310   pfglyph *glyphs = NULL;
00311 
00312   f = fopen(fileName, "r");
00313   if (NULL == f)
00314   {
00315     return NULL;
00316   }
00317 
00318   while (NULL != fgets(buf, sizeof(buf), f))
00319   {
00320     if (0 == strcmp("/*PolyFontVersion\n", buf)) /*--------*/
00321     {
00322       fscanf(f, "%f\n", &version);
00323     }
00324     else if (0 == strcmp("/*fontinfo\n", buf)) /*--------*/
00325     {
00326       fontinfo = (pffont *)calloc(1, sizeof(pffont));
00327       if (NULL == fontinfo)
00328       {
00329         fclose(f);
00330         return NULL;
00331       }
00332       fgets(buf, sizeof(buf), f); /* skip a line */
00333       fscanf(f,
00334              "%f, %f, %f, %f, %d\n",
00335              &fontinfo->minx, &fontinfo->miny,
00336              &fontinfo->maxx, &fontinfo->maxy,
00337              &fontinfo->numglyphs);
00338       /*
00339       printf("fontinfo = %f, %f, %f, %f, %d\n",
00340              fontinfo->minx, fontinfo->miny,
00341              fontinfo->maxx, fontinfo->maxy,
00342              fontinfo->numglyphs);
00343       */
00344       fontinfo->name = fontname;
00345       fontinfo->glyphs = glyphs;
00346       fontinfo->loaded = 1;
00347     }
00348     else if (0 == strcmp("/*fontname\n", buf)) /*--------*/
00349     {
00350       if (NULL != fgets(buf, sizeof(buf), f))
00351       {
00352         int len = strlen(buf);
00353 
00354         if (len >= sizeof(buf))
00355         {
00356           fclose(f);
00357           return NULL;
00358         }
00359 
00360         buf[len - 1] = '\0';
00361 
00362         fontname = calloc(len, sizeof(char));
00363         if (NULL == fontname)
00364         {
00365           fclose(f);
00366           return NULL;
00367         }
00368 
00369         strncpy(fontname, buf, len);
00370       }
00371     }
00372     else if (0 == strcmp("/*glyphcount\n", buf)) /*--------*/
00373     {
00374       fscanf(f, "%d\n", &glyphcount);
00375 
00376       glyphs = (pfglyph *)calloc(glyphcount, sizeof(pfglyph));
00377       if (NULL == glyphs)
00378       {
00379         fclose(f);
00380         return NULL;
00381       }
00382     }
00383     else if (0 == strcmp("/*glyphinfo\n", buf)) /*--------*/
00384     {
00385       int n = 0;
00386       fscanf(f, "%d\n", &n); /* glyph index */
00387 
00388       fgets(buf, sizeof(buf), f); /* skip a line */
00389       fscanf(f,
00390              "%f, %f, %f, %f, %f, %hu, %hu\n",
00391              &glyphs[n].minx, &glyphs[n].miny,
00392              &glyphs[n].maxx, &glyphs[n].maxy,
00393              &glyphs[n].advance,
00394              &glyphs[n].glyph,
00395              &glyphs[n].numsegments);
00396       /*
00397       printf("glyphinfo = %f, %f, %f, %f, %f, %hu, %hu\n",
00398              glyphs[n].minx, glyphs[n].miny,
00399              glyphs[n].maxx, glyphs[n].maxy,
00400              glyphs[n].advance,
00401              glyphs[n].glyph,
00402              glyphs[n].numsegments);
00403       */
00404     }
00405     else if (0 == strcmp("/*glyphdata\n", buf)) /*--------*/
00406     {
00407       int n;
00408       int size;
00409       int i, j;
00410       int segs;
00411       char op[1024];
00412       int points;
00413       pfint16 *data = NULL;
00414 
00415       fscanf(f, "%d,%d\n", &n, &size);
00416 
00417       data = (pfint16 *)calloc(size, sizeof(pfuint16));
00418       if (NULL == data)
00419       {
00420         fclose(f);
00421         return NULL;
00422       }
00423       glyphs[n].segments = data;
00424 
00425       for (i = 0; i < size; )
00426       {
00427         while ((NULL != fgets(buf, sizeof(buf), f)) &&
00428                (0 != strcmp("/*segment\n", buf)))
00429         {
00430         }
00431         fscanf(f, "%d\n", &segs);
00432 
00433         fgets(buf, sizeof(buf), f); /* skip a line */
00434         fscanf(f, "%s\n", &op[0]);
00435         fgets(buf, sizeof(buf), f); /* skip a line */
00436         fscanf(f, "%d\n", &points);
00437 
00438         data[i] = lookupGlOp(op);
00439         i++;
00440         data[i] = points;
00441         i++;
00442 
00443         for (j = 0; j < points; j++)
00444         {
00445           fgets(buf, sizeof(buf), f); /* skip a line */
00446           fscanf(f, "%hd,%hd\n", &data[i], &data[i + 1]);
00447 
00448           i += 2;
00449         }
00450       }
00451     }
00452   }
00453 
00454   fclose(f);
00455   return fontinfo;
00456 }
00457 #endif
00458 
00459 /*-----------------------------------------------*/
00460 
00461 void pfSetScale(SUMOReal s)
00462 {
00463   pfScaleX = pfScaleY = s;
00464 }
00465 
00466 /*-----------------------------------------------*/
00467 
00468 void pfSetScaleXY(SUMOReal sx, SUMOReal sy)
00469 {
00470   pfScaleX = sx;
00471   pfScaleY = sy;
00472 }
00473 
00474 /*-----------------------------------------------*/
00475 
00476 void pfSetPosition(SUMOReal x, SUMOReal y)
00477 {
00478   pfTextX = x;
00479   pfTextY = y;
00480 }
00481 
00482 /*-----------------------------------------------*/
00483 
00484 void pfGetPosition(SUMOReal *x, SUMOReal *y)
00485 {
00486   *x = pfTextX;
00487   *y = pfTextY;
00488 }
00489 
00490 /*-----------------------------------------------*/
00491 
00492 void pfSetSkew(SUMOReal s)
00493 {
00494   pfTextSkew = min(1.0, max(-1.0, s));
00495 }
00496 
00497 /*-----------------------------------------------*/
00498 
00499 void pfSetWeight(int w)
00500 {
00501   pfTextWeight = min(numWeights, max(1, w));
00502 }
00503 
00504 /*-----------------------------------------------*/
00505 
00506 void pfSetAngleR(SUMOReal a)
00507 {
00508   pfTextSin = sin(a);
00509   pfTextCos = cos(a);
00510 }
00511 
00512 /*-----------------------------------------------*/
00513 
00514 void pfSetAngleD(SUMOReal a)
00515 {
00516   pfSetAngleR(a * DtoR);
00517 }
00518 
00519 /*-----------------------------------------------*/
00520 
00521 void pfSetCenter(int onOff)
00522 {
00523   pfCenter = onOff;
00524 }
00525 
00526 /*-----------------------------------------------*/
00527 
00528 static int getCharBBox(wchar_t c, SUMOReal *minx, SUMOReal *miny, SUMOReal *maxx, SUMOReal *maxy)
00529 {
00530   if (NULL != pfCurrentFont)
00531   {
00532     pfglyph *g = pfGetGlyph(c);
00533     if (NULL != g)
00534     {
00535       *minx = g->minx;
00536       *miny = g->miny;
00537 
00538       *maxx = g->maxx;
00539       *maxy = g->maxy;
00540     }
00541     return 0;
00542   }
00543 
00544   *minx = 0;
00545   *miny = 0;
00546   *maxx = 0;
00547   *maxy = 0;
00548 
00549   return -1;
00550 }
00551 
00552 /*-----------------------------------------------*/
00553 
00554 static int getStringBox(char *c, SUMOReal *minx, SUMOReal *miny, SUMOReal *maxx, SUMOReal *maxy)
00555 {
00556   SUMOReal x1, y1, x2, y2;
00557 
00558   if (NULL == c)
00559   {
00560     return -1;
00561   }
00562 
00563   if (-1 == getCharBBox(*c, &x1, &y1, &x2, &y2))
00564   {
00565     return -1;
00566   }
00567 
00568   *minx = x1;
00569   *miny = y1;
00570   *maxx = getCharAdvance(*c);
00571   *maxy = y2;
00572 
00573   c++;
00574 
00575   while (0 != *c)
00576   {
00577     if (-1 == getCharBBox(*c, &x1, &y1, &x2, &y2))
00578     {
00579       return -1;
00580     }
00581 
00582     *miny = min(*miny, y1);
00583     *maxx += getCharAdvance(*c);
00584     *maxy = max(*maxy, y2);
00585 
00586     c++;
00587   }
00588 
00589   return 0;
00590 }
00591 
00592 /*-----------------------------------------------*/
00593 
00594 static int getStringBoxW(wchar_t *c, SUMOReal *minx, SUMOReal *miny, SUMOReal *maxx, SUMOReal *maxy)
00595 {
00596   SUMOReal x1, y1, x2, y2;
00597 
00598   if (NULL == c)
00599   {
00600     return -1;
00601   }
00602 
00603   if (-1 == getCharBBox(*c, &x1, &y1, &x2, &y2))
00604   {
00605     return -1;
00606   }
00607 
00608   *minx = x1;
00609   *miny = y1;
00610   *maxx = getCharAdvance(*c);
00611   *maxy = y2;
00612 
00613   c++;
00614 
00615   while (0 != *c)
00616   {
00617     if (-1 == getCharBBox(*c, &x1, &y1, &x2, &y2))
00618     {
00619       return -1;
00620     }
00621 
00622     *miny = min(*miny, y1);
00623     *maxx += getCharAdvance(*c);
00624     *maxy = max(*maxy, y2);
00625 
00626     c++;
00627   }
00628 
00629   return 0;
00630 }
00631 
00632 /*-----------------------------------------------*/
00633 
00634 int pfSetScaleBox(char *c, SUMOReal w, SUMOReal h)
00635 {
00636   SUMOReal x1, y1, x2, y2;
00637 
00638   if (NULL == c)
00639   {
00640     return -1;
00641   }
00642 
00643   if (-1 == getStringBox(c, &x1, &y1, &x2, &y2))
00644   {
00645     return -1;
00646   }
00647 
00648   pfSetScaleXY((w / (x2 - x1)), (h / (y2 - y1)));
00649   return 0;
00650 }
00651 
00652 /*-----------------------------------------------*/
00653 
00654 int pfSetScaleBoxW(wchar_t *c, SUMOReal w, SUMOReal h)
00655 {
00656   SUMOReal x1, y1, x2, y2;
00657 
00658   if (NULL == c)
00659   {
00660     return -1;
00661   }
00662 
00663   if (-1 == getStringBoxW(c, &x1, &y1, &x2, &y2))
00664   {
00665     return -1;
00666   }
00667 
00668   pfSetScaleXY((w / (x2 - x1)), (h / (y2 - y1)));
00669   return 0;
00670 }
00671 
00672 /*-----------------------------------------------*/
00673 
00674 char *pfGetFontName()
00675 {
00676   char *name = NULL;
00677 
00678   if (NULL != pfCurrentFont)
00679   {
00680     name = pfCurrentFont->name;
00681   }
00682 
00683   return name;
00684 }
00685 
00686 /*-----------------------------------------------*/
00687 
00688 pffont *pfGetCurrentFont()
00689 {
00690   return pfCurrentFont;
00691 }
00692 
00693 /*-----------------------------------------------*/
00694 
00695 int pfGetFontBBox(SUMOReal *minx, SUMOReal *miny, SUMOReal *maxx, SUMOReal *maxy)
00696 {
00697   if (NULL != pfCurrentFont)
00698   {
00699     *minx = pfScaleX * pfCurrentFont->minx;
00700     *miny = pfScaleY * pfCurrentFont->miny;
00701 
00702     *maxx = pfScaleX * pfCurrentFont->maxx;
00703     *maxy = pfScaleY * pfCurrentFont->maxy;
00704 
00705     if (pfTextSkew > 0)
00706     {
00707       *minx = pfSkew(*minx, *miny);
00708       *maxx = pfSkew(*maxx, *maxy);
00709     }
00710     else
00711     {
00712       *minx = pfSkew(*minx, *maxy);
00713       *maxx = pfSkew(*maxx, *miny);
00714     }
00715 
00716     return 0;
00717   }
00718 
00719   *minx = 0;
00720   *miny = 0;
00721   *maxx = 0;
00722   *maxy = 0;
00723 
00724   return -1;
00725 }
00726 
00727 /*-----------------------------------------------*/
00728 
00729 SUMOReal pfGetFontHeight()
00730 {
00731   SUMOReal minx, miny, maxx, maxy;
00732 
00733   if (-1 != pfGetFontBBox(&minx, &miny, &maxx, &maxy))
00734   {
00735     return maxy - miny;
00736   }
00737 
00738   return 0.0;
00739 }
00740 
00741 /*-----------------------------------------------*/
00742 
00743 SUMOReal pfGetFontWidth()
00744 {
00745   SUMOReal minx, miny, maxx, maxy;
00746 
00747   if (-1 != pfGetFontBBox(&minx, &miny, &maxx, &maxy))
00748   {
00749     return maxx - minx;
00750   }
00751 
00752   return 0.0;
00753 }
00754 
00755 /*-----------------------------------------------*/
00756 
00757 SUMOReal pfGetFontAscent()
00758 {
00759   SUMOReal minx, miny, maxx, maxy;
00760 
00761   if (-1 != pfGetFontBBox(&minx, &miny, &maxx, &maxy))
00762   {
00763     return maxy;
00764   }
00765 
00766   return 0.0;
00767 }
00768 
00769 /*-----------------------------------------------*/
00770 
00771 SUMOReal pfGetFontDescent()
00772 {
00773   SUMOReal minx, miny, maxx, maxy;
00774 
00775   if (-1 != pfGetFontBBox(&minx, &miny, &maxx, &maxy))
00776   {
00777     return miny;
00778   }
00779 
00780   return 0.0;
00781 }
00782 
00783 /*-----------------------------------------------*/
00784 
00785 int pfGetFontNumGlyphs()
00786 {
00787   if (NULL != pfCurrentFont)
00788   {
00789     return pfCurrentFont->numglyphs;
00790   }
00791 
00792   return 0;
00793 }
00794 
00795 /*-----------------------------------------------*/
00796 
00797 wchar_t pfGetChar(int g)
00798 {
00799   wchar_t c = 0;
00800   int ng = -1;
00801 
00802   if (NULL != pfCurrentFont)
00803   {
00804     ng = pfCurrentFont->numglyphs;
00805     if ((g >= 0) && (g < ng))
00806     {
00807       c = pfCurrentFont->glyphs[g].glyph;
00808     }
00809   }
00810 
00811   return c;
00812 }
00813 
00814 /*-----------------------------------------------*/
00815 
00816 static int comp(const void *key, const void *target)
00817 {
00818   pfglyph *k = (pfglyph *)key;
00819   pfglyph *t = (pfglyph *)target;
00820 
00821   return (k->glyph) - (t->glyph);
00822 }
00823 
00824 /*-----------------------------------------------*/
00825 
00826 static pfglyph *pfFindGlyph(pfglyph *glyphs, int numglyphs, pfglyph *find)
00827 {
00828   return (pfglyph *) bsearch((void *)find, (void *)glyphs, numglyphs, sizeof(pfglyph), comp);
00829 }
00830 
00831 /*-----------------------------------------------*/
00832 
00833 static pfglyph *pfGetGlyph(wchar_t c)
00834 {
00835   pfglyph *g = NULL;
00836   pfglyph key;
00837 
00838   if (NULL == pfCurrentFont)
00839   {
00840     return NULL;
00841   }
00842 
00843   key.glyph = c;
00844   g = pfFindGlyph(pfCurrentFont->glyphs, pfCurrentFont->numglyphs, &key);
00845 
00846   return g;
00847 }
00848 
00849 /*-----------------------------------------------*/
00850 
00851 static SUMOReal getCharAdvance(wchar_t c)
00852 {
00853   pfglyph *g = pfGetGlyph(c);
00854 
00855   if (NULL == g)
00856   {
00857     return 0.0;
00858   }
00859 
00860   return g->advance;
00861 }
00862 
00863 /*-----------------------------------------------*/
00864 
00865 SUMOReal pfGetCharAdvance(wchar_t c)
00866 {
00867   pfglyph *g = pfGetGlyph(c);
00868 
00869   if (NULL == g)
00870   {
00871     return 0.0;
00872   }
00873 
00874   return (g->advance * pfScaleX);
00875 }
00876 
00877 /*-----------------------------------------------*/
00878 
00879 int pfGetCharBBox(wchar_t c, SUMOReal *minx, SUMOReal *miny, SUMOReal *maxx, SUMOReal *maxy)
00880 {
00881   if (0 == getCharBBox(c, minx, miny, maxx, maxy))
00882   {
00883     *minx = pfScaleX * (*minx);
00884     *miny = pfScaleY * (*miny);
00885 
00886     *maxx = pfScaleX * (*maxx);
00887     *maxy = pfScaleY * (*maxy);
00888 
00889     if (pfTextSkew > 0)
00890     {
00891       *minx = pfSkew(*minx, *miny);
00892       *maxx = pfSkew(*maxx, *maxy);
00893     }
00894     else
00895     {
00896       *minx = pfSkew(*minx, *maxy);
00897       *maxx = pfSkew(*maxx, *miny);
00898     }
00899 
00900 
00901     return 0;
00902   }
00903 
00904   *minx = 0;
00905   *miny = 0;
00906   *maxx = 0;
00907   *maxy = 0;
00908 
00909   return -1;
00910 }
00911 
00912 /*-----------------------------------------------*/
00913 
00914 SUMOReal pfGetCharHeight(wchar_t c)
00915 {
00916   SUMOReal minx, miny, maxx, maxy;
00917 
00918   if (-1 != pfGetCharBBox(c, &minx, &miny, &maxx, &maxy))
00919   {
00920     return maxy - miny;
00921   }
00922 
00923   return 0.0;
00924 }
00925 
00926 /*-----------------------------------------------*/
00927 
00928 SUMOReal pfGetCharWidth(wchar_t c)
00929 {
00930   SUMOReal minx, miny, maxx, maxy;
00931 
00932   if (-1 != pfGetCharBBox(c, &minx, &miny, &maxx, &maxy))
00933   {
00934     return maxx - minx;
00935   }
00936 
00937   return 0.0;
00938 }
00939 
00940 /*-----------------------------------------------*/
00941 
00942 SUMOReal pfGetCharAscent(wchar_t c)
00943 {
00944   SUMOReal minx, miny, maxx, maxy;
00945 
00946   if (-1 != pfGetCharBBox(c, &minx, &miny, &maxx, &maxy))
00947   {
00948     return maxy;
00949   }
00950 
00951   return 0.0;
00952 }
00953 
00954 /*-----------------------------------------------*/
00955 
00956 SUMOReal pfGetCharDescent(wchar_t c)
00957 {
00958   SUMOReal minx, miny, maxx, maxy;
00959 
00960   if (-1 != pfGetCharBBox(c, &minx, &miny, &maxx, &maxy))
00961   {
00962     return miny;
00963   }
00964 
00965   return 0.0;
00966 }
00967 
00968 /*-----------------------------------------------*/
00969 
00970 static int drawWideChar(/*SDL_Surface *s,*/ wchar_t c)
00971 {
00972   int i;
00973   int j;
00974   int k;
00975   pfglyph *g = pfGetGlyph(c);
00976   pfint16 *d = NULL;
00977   int segs = 0;
00978   int prim = 0;
00979   int points = 0;
00980   SUMOReal gx, gy;
00981   SUMOReal ox, oy;
00982   SUMOReal tmp = -100.0;
00983 
00984   if (NULL == g)
00985   {
00986     return -1;
00987   }
00988 
00989   ox = 0.0;
00990   oy = 0.0;
00991   if (pfCenter)
00992   {
00993     oy = pfScaleY * ((g->maxy + g->miny) / 2.0);
00994     ox = pfScaleX * ((g->maxx + g->minx) / 2.0);
00995   }
00996 
00997   for (k = 0; k < pfTextWeight; k++)
00998   {
00999     segs = g->numsegments;
01000     d = g->segments;
01001 
01002     for (i = 0; i < segs; i++)
01003     {
01004       prim = *d++;
01005       points = *d++;
01006 
01007       glBegin(prim);//sglBegin(s, prim);
01008       for (j = 0; j < points; j++)
01009       {
01010         gx = unfix(*d++);
01011         gy = unfix(*d++);
01012 
01013         gx = (gx * pfScaleX);
01014         gy = (gy * pfScaleY);
01015 
01016         gx += weightOffset[k].x;
01017         gy += weightOffset[k].y;
01018 
01019         gx = pfSkew(gx, gy);
01020 
01021         tmp = gx;
01022         gx = (pfTextX - ox) + ((pfTextCos * tmp) - (pfTextSin * gy));
01023         gy = (pfTextY + oy) - ((pfTextSin * tmp) + (pfTextCos * gy));
01024 
01025         glVertex2f(gx, gy);//sglVertex2f(gx, gy);
01026       }
01027       glEnd();//sglEnd();
01028     }
01029   }
01030 
01031   /*
01032     sglColor3f(0.0, 1.0, 0.0);
01033     sglBegin(s, GL_LINES);
01034     sglVertex2f(pfTextX - pfScaleX, pfTextY);
01035     sglVertex2f(pfTextX + pfScaleX, pfTextY);
01036     sglEnd();
01037 
01038     sglColor3f(0.0, 1.0, 0.0);
01039     sglBegin(s, GL_LINES);
01040     sglVertex2f(pfTextX, pfTextY - pfScaleY);
01041     sglVertex2f(pfTextX, pfTextY + pfScaleX);
01042     sglEnd();
01043   */
01044 
01045   tmp = (g->advance * pfScaleX);
01046   pfTextX += tmp * pfTextCos;
01047   pfTextY -= tmp * pfTextSin;
01048 
01049   return 0;
01050 }
01051 
01052 /*-----------------------------------------------*/
01053 
01054 int pfDrawChar(/*SDL_Surface *s,*/ wchar_t c)
01055 {
01056   int value = 0;
01057 /*
01058   if (NULL == s)
01059   {
01060     return -1;
01061   }
01062 */
01063   value = drawWideChar(/*s,*/ c);
01064 
01065   return value;
01066 }
01067 
01068 /*-----------------------------------------------*/
01069 
01070 int pfDrawString(/*SDL_Surface *s,*/ const char *c)
01071 {
01072     /*
01073   if ((NULL == s) || (NULL == c))
01074   {
01075     return -1;
01076   }
01077 */
01078   while (0 != *c)
01079   {
01080     drawWideChar(/*s,*/ *c);
01081     c++;
01082   }
01083 
01084   return 0;
01085 }
01086 
01087 /*-----------------------------------------------*/
01088 
01089 int pfDrawStringW(/*SDL_Surface *s, */wchar_t *c)
01090 {
01091     /*
01092   if ((NULL == s) || (NULL == c))
01093   {
01094     return -1;
01095   }
01096 */
01097   while (0 != *c)
01098   {
01099     drawWideChar(/*s,*/ *c);
01100     c++;
01101   }
01102 
01103   return 0;
01104 }
01105 
01106 /*-----------------------------------------------*/
01107 
01108 SUMOReal
01109 pfdkGetStringWidth(const char *c)
01110 {
01111     SUMOReal w = 0;
01112     while (0 != *c) {
01113         w += pfGetCharAdvance(/*s,*/ *c);
01114         c++;
01115     }
01116     return w;
01117 }
01118 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines