SUMO - Simulation of Urban MObility
|
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