00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #if !defined(WIN32) || defined(__GNUC__)
00069 #include <unistd.h>
00070 #else
00071 #define F_OK 1
00072 #include <stdio.h>
00073 int access( char *filename, int flag ) {
00074 FILE *infile ;
00075 infile = fopen( filename, "r" ) ;
00076 if ( infile != NULL ) {
00077 fclose(infile) ;
00078 return 0 ;
00079 } else {
00080 return 1 ;
00081 }
00082 }
00083 #endif
00084
00085 #define makeunixslash( b ) do { char *I; for (I=b;*I!=0;*I++) if (*I=='\\') *I='/';}while(0)
00086
00087 #include "plDevs.h"
00088 #include "plplotP.h"
00089 #include "drivers.h"
00090 #ifdef HAVE_FREETYPE
00091 #include "plfreetype.h"
00092 #include "plfci-truetype.h"
00093
00094 #define FT_Data _FT_Data_
00095
00096
00097 PLDLLIMPEXP_DATA(FCI_to_FontName_Table) FontLookup[N_TrueTypeLookup];
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 #define TEXT_SCALING_FACTOR .7
00109
00110
00111
00112
00113 #define NTEXT_ALLOC 1024
00114
00115
00116
00117
00118
00119 #define Debug6(a,b,c,d,e,f) do {if (pls->debug){fprintf(stderr,a,b,c,d,e,f);}}while(0)
00120
00121
00122
00123
00124
00125
00126 void plD_FreeType_init(PLStream *pls);
00127 void plD_render_freetype_text (PLStream *pls, EscText *args);
00128 void plD_FreeType_Destroy(PLStream *pls);
00129 void pl_set_extended_cmap0(PLStream *pls, int ncol0_width, int ncol0_org);
00130 void pl_RemakeFreeType_text_from_buffer (PLStream *pls);
00131 void plD_render_freetype_sym (PLStream *pls, EscText *args);
00132
00133
00134
00135 static void FT_PlotChar(PLStream *pls,FT_Data *FT, FT_GlyphSlot slot, int x, int y, short colour );
00136 static void FT_SetFace( PLStream *pls, PLUNICODE fci );
00137 static PLFLT CalculateIncrement( int bg, int fg, int levels);
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void FT_WriteStrW(PLStream *pls,const PLUNICODE *text, short len, int x, int y);
00147 static void FT_StrX_YW(PLStream *pls,const PLUNICODE *text, short len, int *xx, int *yy);
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 void
00160 FT_StrX_YW(PLStream *pls, const PLUNICODE *text, short len, int *xx, int *yy)
00161 {
00162 FT_Data *FT=(FT_Data *)pls->FT;
00163 short i=0;
00164 FT_Vector akerning;
00165 int x=0,y=0;
00166 char esc;
00167
00168 plgesc(&esc);
00169
00170
00171
00172
00173
00174
00175
00176
00177 y -= FT->face->size->metrics.height;
00178
00179
00180 for (i=0;i<len;i++) {
00181 if ((text[i]==esc)&&(text[i-1]!=esc)) {
00182 if (text[i+1]==esc) continue;
00183
00184 switch(text[i+1]) {
00185
00186 case 'u':
00187 case 'd':
00188 case 'U':
00189 case 'D':
00190 i++;
00191 break;
00192 }
00193
00194 } else if (text[i] & PL_FCI_MARK) {
00195
00196 FT_SetFace(pls , text[i]);
00197 } else {
00198
00199
00200 if ((i>0)&&FT_HAS_KERNING(FT->face)) {
00201 FT_Get_Kerning( FT->face,
00202 text[i-1],
00203 text[i],
00204 ft_kerning_default,
00205 &akerning );
00206 x+= (akerning.x >> 6);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 FT_Load_Char( FT->face, text[i], FT_LOAD_MONOCHROME+FT_LOAD_RENDER);
00220
00221
00222
00223
00224
00225
00226
00227 x += (FT->face->glyph->advance.x);
00228 y -= (FT->face->glyph->advance.y);
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 *yy = y;
00244 *xx = x;
00245
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 void
00257 FT_WriteStrW(PLStream *pls, const PLUNICODE *text, short len, int x, int y)
00258 {
00259 FT_Data *FT=(FT_Data *)pls->FT;
00260 short i=0,last_char=-1;
00261 FT_Vector akerning, adjust;
00262 char esc;
00263
00264 plgesc(&esc);
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 #ifdef DODGIE_DECENDER_HACK
00284 adjust.y= (FT->face->descender >> 6)*3;
00285 #else
00286 adjust.y= (FT->face->descender >> 6);
00287 #endif
00288
00289
00290
00291
00292
00293
00294
00295 adjust.x=0;
00296 adjust.y=0;
00297 FT_Vector_Transform( &adjust, &FT->matrix);
00298 x+=adjust.x;
00299 y-=adjust.y;
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 x <<= 6;
00312 y <<= 6;
00313
00314
00315
00316 for (i=0; i<len; i++) {
00317 if ((text[i]==esc)&&(text[i-1]!=esc)) {
00318 if (text[i+1]==esc) continue;
00319
00320 switch(text[i+1]) {
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 case 'u':
00332 case 'U':
00333 adjust.y = FT->face->size->metrics.height / 2;
00334 adjust.x=0;
00335 FT_Vector_Transform( &adjust, &FT->matrix);
00336 x+=adjust.x;
00337 y-=adjust.y;
00338 i++;
00339 break;
00340
00341 case 'd':
00342 case 'D':
00343 adjust.y = -FT->face->size->metrics.height / 2;
00344 adjust.x=0;
00345 FT_Vector_Transform( &adjust, &FT->matrix);
00346 x+=adjust.x;
00347 y-=adjust.y;
00348 i++;
00349 break;
00350 }
00351
00352 } else if (text[i] & PL_FCI_MARK) {
00353
00354 FT_SetFace(pls , text[i]);
00355 FT=(FT_Data *)pls->FT;
00356 FT_Set_Transform( FT->face, &FT->matrix, &FT->pos );
00357 } else {
00358
00359 if ((last_char!=-1)&&(i>0)&&FT_HAS_KERNING(FT->face)) {
00360 FT_Get_Kerning( FT->face,
00361 text[last_char],
00362 text[i],
00363 ft_kerning_default, &akerning );
00364 x += akerning.x;
00365 y -= akerning.y;
00366
00367 }
00368
00369
00370 FT_Load_Char( FT->face, text[i], (FT->smooth_text==0) ? FT_LOAD_MONOCHROME+FT_LOAD_RENDER : FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT);
00371 FT_PlotChar(pls,FT, FT->face->glyph,
00372 ROUND (x / 64.0), ROUND (y / 64.0), 2 );
00373
00374 x += FT->face->glyph->advance.x;
00375 y -= FT->face->glyph->advance.y;
00376
00377 last_char=i;
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389 void
00390 FT_PlotChar(PLStream *pls, FT_Data *FT, FT_GlyphSlot slot,
00391 int x, int y, short colour )
00392 {
00393 unsigned char bittest;
00394 short i,k,j;
00395 int n=slot->bitmap.pitch;
00396 int current_pixel_colour;
00397 int R,G,B;
00398 PLFLT alpha_a,alpha_b;
00399 int xx;
00400 short imin, imax, kmin, kmax;
00401
00402
00403 PLINT clipxmin, clipymin, clipxmax,clipymax, tmp;
00404 PLINT clpxmi, clpxma, clpymi, clpyma;
00405
00406
00407 clipxmin=pls->clpxmi;
00408 clipxmax=pls->clpxma;
00409 clipymin=pls->clpymi;
00410 clipymax=pls->clpyma;
00411
00412 if (plsc->difilt) {
00413 difilt(&clipxmin,&clipymin,1,&clpxmi,&clpxma,&clpymi,&clpyma);
00414 difilt(&clipxmax,&clipymax,1,&clpxmi,&clpxma,&clpymi,&clpyma);
00415 }
00416
00417
00418 if( FT->scale!=0.0 ) {
00419 clipxmin = clipxmin/FT->scale;
00420 clipxmax = clipxmax/FT->scale;
00421 if (FT->invert_y==1) {
00422 clipymin=FT->ymax-(clipymin/FT->scale);
00423 clipymax=FT->ymax-(clipymax/FT->scale);
00424 }
00425 else {
00426 clipymin=clipymin/FT->scale;
00427 clipymax=clipymax/FT->scale;
00428 }
00429 }
00430 else {
00431 clipxmin=clipxmin/FT->scalex;
00432 clipxmax=clipxmax/FT->scalex;
00433
00434 if (FT->invert_y==1) {
00435 clipymin=FT->ymax-(clipymin/FT->scaley);
00436 clipymax=FT->ymax-(clipymax/FT->scaley);
00437 }
00438 else {
00439 clipymin=clipymin/FT->scaley;
00440 clipymax=clipymax/FT->scaley;
00441 }
00442 }
00443 if (clipxmin > clipxmax) {
00444 tmp = clipxmax;
00445 clipxmax = clipxmin;
00446 clipxmin = tmp;
00447 }
00448 if (clipymin > clipymax) {
00449 tmp = clipymax;
00450 clipymax = clipymin;
00451 clipymin = tmp;
00452 }
00453
00454
00455
00456
00457
00458 if (slot->bitmap.pixel_mode==ft_pixel_mode_mono) {
00459 x+=slot->bitmap_left;
00460 y-=slot->bitmap_top;
00461
00462 imin = MAX(0,clipymin-y);
00463 imax = MIN(slot->bitmap.rows,clipymax-y);
00464 for(i=imin;i<imax;i++) {
00465 for (k=0;k<n;k++) {
00466 bittest=128;
00467 for (j=0;j<8;j++) {
00468 if ((bittest&(unsigned char)slot->bitmap.buffer[(i*n)+k])==bittest) {
00469 xx = x+(k*8)+j;
00470 if ( (xx >= clipxmin) && (xx <= clipxmax) )
00471 FT->pixel(pls, xx, y+i);
00472 }
00473 bittest>>=1;
00474 }
00475 }
00476 }
00477 }
00478
00479
00480
00481 else {
00482 x+=slot->bitmap_left;
00483 y-=slot->bitmap_top;
00484
00485 imin = MAX(0,clipymin-y);
00486 imax = MIN(slot->bitmap.rows,clipymax-y);
00487 kmin = MAX(0,clipxmin-x);
00488 kmax = MIN(slot->bitmap.width,clipxmax-x);
00489 for(i=imin;i<imax;i++)
00490 {
00491 for (k=kmin;k<kmax;k++)
00492 {
00493 FT->shade=(slot->bitmap.buffer[(i*slot->bitmap.width)+k]);
00494 if (FT->shade>0)
00495 {
00496 if ((FT->BLENDED_ANTIALIASING==1)&&(FT->read_pixel!=NULL))
00497
00498 {
00499 if (FT->shade==255)
00500 {
00501 FT->pixel(pls,x+k,y+i);
00502 }
00503 else
00504 {
00505 current_pixel_colour=FT->read_pixel(pls,x+k,y+i);
00506
00507 G=GetGValue(current_pixel_colour);
00508 R=GetRValue(current_pixel_colour);
00509 B=GetBValue(current_pixel_colour);
00510 alpha_a=(float)FT->shade/255.0;
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 R=(((plsc->cmap0[pls->icol0].r-R)*alpha_a)+R);
00528 G=(((plsc->cmap0[pls->icol0].g-G)*alpha_a)+G);
00529 B=(((plsc->cmap0[pls->icol0].b-B)*alpha_a)+B);
00530
00531 FT->set_pixel(pls,x+k,y+i,RGB(R>255 ? 255 : R,G>255 ? 255 : G,B>255 ? 255 : B));
00532 }
00533 }
00534 else
00535 {
00536 FT->col_idx=FT->ncol0_width-((FT->ncol0_width*FT->shade)/255);
00537 FT->last_icol0=pls->icol0;
00538 plcol0(pls->icol0+(FT->col_idx*(FT->ncol0_org-1)));
00539 FT->pixel(pls,x+k,y+i);
00540 plcol0(FT->last_icol0);
00541 }
00542 }
00543 }
00544 }
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 void plD_FreeType_init(PLStream *pls)
00557 {
00558 FT_Data *FT;
00559 char *a;
00560
00561 char font_dir[PLPLOT_MAX_PATH];
00562
00563 const char *env_font_names[N_TrueTypeLookup] = {
00564 "PLPLOT_FREETYPE_SANS_FONT",
00565 "PLPLOT_FREETYPE_SERIF_FONT",
00566 "PLPLOT_FREETYPE_MONO_FONT",
00567 "PLPLOT_FREETYPE_SCRIPT_FONT",
00568 "PLPLOT_FREETYPE_SYMBOL_FONT",
00569 "PLPLOT_FREETYPE_SANS_ITALIC_FONT",
00570 "PLPLOT_FREETYPE_SERIF_ITALIC_FONT",
00571 "PLPLOT_FREETYPE_MONO_ITALIC_FONT",
00572 "PLPLOT_FREETYPE_SCRIPT_ITALIC_FONT",
00573 "PLPLOT_FREETYPE_SYMBOL_ITALIC_FONT",
00574 "PLPLOT_FREETYPE_SANS_OBLIQUE_FONT",
00575 "PLPLOT_FREETYPE_SERIF_OBLIQUE_FONT",
00576 "PLPLOT_FREETYPE_MONO_OBLIQUE_FONT",
00577 "PLPLOT_FREETYPE_SCRIPT_OBLIQUE_FONT",
00578 "PLPLOT_FREETYPE_SYMBOL_OBLIQUE_FONT",
00579 "PLPLOT_FREETYPE_SANS_BOLD_FONT",
00580 "PLPLOT_FREETYPE_SERIF_BOLD_FONT",
00581 "PLPLOT_FREETYPE_MONO_BOLD_FONT",
00582 "PLPLOT_FREETYPE_SCRIPT_BOLD_FONT",
00583 "PLPLOT_FREETYPE_SYMBOL_BOLD_FONT",
00584 "PLPLOT_FREETYPE_SANS_BOLD_ITALIC_FONT",
00585 "PLPLOT_FREETYPE_SERIF_BOLD_ITALIC_FONT",
00586 "PLPLOT_FREETYPE_MONO_BOLD_ITALIC_FONT",
00587 "PLPLOT_FREETYPE_SCRIPT_BOLD_ITALIC_FONT",
00588 "PLPLOT_FREETYPE_SYMBOL_BOLD_ITALIC_FONT",
00589 "PLPLOT_FREETYPE_SANS_BOLD_OBLIQUE_FONT",
00590 "PLPLOT_FREETYPE_SERIF_BOLD_OBLIQUE_FONT",
00591 "PLPLOT_FREETYPE_MONO_BOLD_OBLIQUE_FONT",
00592 "PLPLOT_FREETYPE_SCRIPT_BOLD_OBLIQUE_FONT",
00593 "PLPLOT_FREETYPE_SYMBOL_BOLD_OBLIQUE_FONT"
00594 };
00595 short i;
00596
00597 #if defined(MSDOS) || defined(WIN32)
00598 static char *default_font_names[]={"arial.ttf","times.ttf","timesi.ttf","arial.ttf",
00599 "symbol.ttf"};
00600 char WINDIR_PATH[PLPLOT_MAX_PATH];
00601 char *b;
00602 b=getenv("WINDIR");
00603 strncpy(WINDIR_PATH,b,PLPLOT_MAX_PATH-1);
00604 WINDIR_PATH[PLPLOT_MAX_PATH-1] = '\0';
00605 #else
00606 const char *default_unix_font_dir=PL_FREETYPE_FONT_DIR;
00607 #endif
00608
00609
00610 if (pls->FT) {
00611 plwarn("Freetype seems already to have been initialised!");
00612 return;
00613 }
00614
00615 if ((pls->FT=calloc(1, (size_t)sizeof(FT_Data)))==NULL)
00616 plexit("Could not allocate memory for Freetype");
00617
00618 FT=(FT_Data *)pls->FT;
00619
00620 if ((FT->textbuf=calloc(NTEXT_ALLOC, 1))==NULL)
00621 plexit("Could not allocate memory for Freetype text buffer");
00622
00623 if ( FT_Init_FreeType( &FT->library ) )
00624 plexit("Could not initialise Freetype library");
00625
00626
00627 FT->fci=PL_FCI_IMPOSSIBLE;
00628
00629 #if defined(MSDOS) || defined(WIN32)
00630
00631
00632
00633
00634
00635
00636
00637
00638 if (WINDIR_PATH==NULL)
00639 {
00640 if (access("c:\\windows\\fonts\\arial.ttf", F_OK)==0) {
00641 strcpy(font_dir,"c:/windows/fonts/");
00642 }
00643 else if ( access("c:\\windows\\system\\arial.ttf", F_OK)==0) {
00644 strcpy(font_dir,"c:/windows/system/");
00645 }
00646 else
00647 plwarn("Could not find font path; I sure hope you have defined fonts manually !");
00648 }
00649 else
00650 {
00651 strncat(WINDIR_PATH,"\\fonts\\arial.ttf",PLPLOT_MAX_PATH-1-strlen(WINDIR_PATH));
00652 if (access(WINDIR_PATH, F_OK)==0)
00653 {
00654 b=strrchr(WINDIR_PATH,'\\');
00655 b++;
00656 *b=0;
00657 makeunixslash(WINDIR_PATH);
00658 strcpy(font_dir,WINDIR_PATH);
00659 }
00660 else
00661 plwarn("Could not find font path; I sure hope you have defined fonts manually !");
00662 }
00663
00664 if (pls->debug) fprintf( stderr, "%s\n", font_dir ) ;
00665 #else
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 if ((a = getenv("PLPLOT_FREETYPE_FONT_DIR")) != NULL)
00676 strncpy(font_dir,a,PLPLOT_MAX_PATH-1);
00677 else
00678 strncpy(font_dir,default_unix_font_dir,PLPLOT_MAX_PATH-1);
00679
00680 font_dir[PLPLOT_MAX_PATH-1] = '\0';
00681 #endif
00682
00683
00684
00685
00686
00687
00688
00689 for (i=0; i<N_TrueTypeLookup; i++) {
00690 if ((a = getenv(env_font_names[i])) != NULL) {
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 #ifdef MSDOS
00702 if (a[1]==':')
00703 #else
00704 if ((a[0]=='/')||(a[0]=='~'))
00705 #endif
00706 strncpy(FT->font_name[i],a,PLPLOT_MAX_PATH-1);
00707
00708 else {
00709 strncpy(FT->font_name[i],font_dir,PLPLOT_MAX_PATH-1);
00710 strncat(FT->font_name[i],a,PLPLOT_MAX_PATH-1-strlen(FT->font_name[i]));
00711 }
00712
00713 } else {
00714 strncpy(FT->font_name[i],font_dir,PLPLOT_MAX_PATH-1);
00715 strncat(FT->font_name[i],(char *)TrueTypeLookup[i].pfont,PLPLOT_MAX_PATH-1-strlen(FT->font_name[i]));
00716 }
00717 FT->font_name[i][PLPLOT_MAX_PATH-1] = '\0';
00718
00719 {
00720 FILE *infile ;
00721 if ( (infile=fopen(FT->font_name[i], "r"))==NULL) {
00722 char msgbuf[1024];
00723 snprintf(msgbuf, 1024,
00724 "plD_FreeType_init: Could not find the freetype compatible font:\n %s",
00725 FT->font_name[i]);
00726 plwarn(msgbuf);
00727 } else {
00728 fclose(infile);
00729 }
00730 }
00731 FontLookup[i].fci = TrueTypeLookup[i].fci;
00732 FontLookup[i].pfont = (unsigned char *)FT->font_name[i];
00733 }
00734
00735
00736
00737
00738
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748 void FT_SetFace( PLStream *pls, PLUNICODE fci)
00749 {
00750 FT_Data *FT=(FT_Data *)pls->FT;
00751 double font_size = pls->chrht * 72/25.4;
00752
00753
00754 FT->chrht=pls->chrht;
00755 FT->xdpi=pls->xdpi;
00756 FT->ydpi=pls->ydpi;
00757
00758 if (fci != FT->fci) {
00759 char *font_name = plP_FCI2FontName(fci, FontLookup, N_TrueTypeLookup);
00760 if (font_name == NULL) {
00761 if (FT->fci == PL_FCI_IMPOSSIBLE)
00762 plexit("FT_SetFace: Bad FCI and no previous valid font to fall back on");
00763 else
00764 plwarn("FT_SetFace: Bad FCI. Falling back to previous font.");
00765 } else {
00766 FT->fci=fci;
00767
00768 if (FT->face!=NULL) {
00769 FT_Done_Face(FT->face);
00770 FT->face=NULL;
00771 }
00772
00773 if (FT->face==NULL) {
00774 if (FT_New_Face( FT->library,font_name, 0,&FT->face))
00775 plexit("FT_SetFace: Error loading a font in freetype");
00776 }
00777 }
00778 }
00779 FT_Set_Char_Size(FT->face,0,
00780 font_size * 64/TEXT_SCALING_FACTOR,pls->xdpi,
00781 pls->ydpi );
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 void plD_render_freetype_text (PLStream *pls, EscText *args)
00793 {
00794 FT_Data *FT=(FT_Data *)pls->FT;
00795 int x,y;
00796 int w=0,h=0;
00797 PLFLT *t = args->xform;
00798 FT_Matrix matrix;
00799 PLFLT angle=PI*pls->diorot/2;
00800
00801
00802
00803
00804
00805 PLFLT Sin_A,Cos_A;
00806 FT_Vector adjust;
00807 PLUNICODE fci;
00808 FT_Fixed height;
00809 PLFLT height_factor;
00810
00811 if ((args->string!=NULL)||(args->unicode_array_len>0))
00812 {
00813
00814
00815
00816
00817
00818
00819 plgfci(&fci);
00820 if ((FT->fci!=fci)||(FT->chrht!=pls->chrht)||(FT->xdpi!=pls->xdpi)||(FT->ydpi!=pls->ydpi))
00821 FT_SetFace(pls,fci);
00822
00823
00824
00825
00826 Debug6("%s %d %d %d %d\n","plD_render_freetype_text:",
00827 FT->face->underline_position>>6,
00828 FT->face->descender>>6,
00829 FT->face->ascender>>6,
00830 ((FT->face->underline_position*-1)+FT->face->ascender)>>6);
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 FT->matrix.xx =0x10000;
00843 FT->matrix.xy =0x00000;
00844 FT->matrix.yx =0x00000;
00845 FT->matrix.yy =0x10000;
00846
00847 FT_Vector_Transform( &FT->pos, &FT->matrix);
00848 FT_Set_Transform( FT->face, &FT->matrix, &FT->pos );
00849
00850 FT_StrX_YW(pls,args->unicode_array,args->unicode_array_len,&w, &h);
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 height_factor = (PLFLT) (FT->face->ascender - FT->face->descender)
00876 / FT->face->ascender;
00877 height = (FT_Fixed) (0x10000 * height_factor);
00878
00879 #ifdef DJGPP
00880 FT->matrix.xx = height * t[0];
00881 FT->matrix.xy = height * t[2];
00882 FT->matrix.yx = height * t[1];
00883 FT->matrix.yy = height * t[3];
00884 #else
00885 FT->matrix.xx = height * t[0];
00886 FT->matrix.xy = height * t[1];
00887 FT->matrix.yx = height * t[2];
00888 FT->matrix.yy = height * t[3];
00889 #endif
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 Cos_A=cos(angle);
00900 Sin_A=sin(angle);
00901
00902 matrix.xx =(FT_Fixed)0x10000*Cos_A;
00903
00904 #ifdef DJGPP
00905 matrix.xy =(FT_Fixed)0x10000*Sin_A*-1;
00906 matrix.yx =(FT_Fixed)0x10000*Sin_A;
00907 #else
00908 matrix.xy =(FT_Fixed)0x10000*Sin_A;
00909 matrix.yx =(FT_Fixed)0x10000*Sin_A*-1;
00910 #endif
00911
00912 matrix.yy =(FT_Fixed)0x10000*Cos_A;
00913
00914 FT_Matrix_Multiply(&matrix,&FT->matrix);
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 FT_Vector_Transform( &FT->pos, &FT->matrix);
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 FT_Set_Transform( FT->face, &FT->matrix, &FT->pos );
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 if( FT->scale!=0.0 ) {
00955 x=args->x/FT->scale;
00956
00957 if (FT->invert_y==1)
00958 y=FT->ymax-(args->y/FT->scale);
00959 else
00960 y=args->y/FT->scale;
00961 } else {
00962 x=args->x/FT->scalex;
00963
00964 if (FT->invert_y==1)
00965 y=FT->ymax-(args->y/FT->scaley);
00966 else
00967 y=args->y/FT->scaley;
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 #ifdef DODGIE_DECENDER_HACK
00993 adjust.y=h;
00994 #else
00995 adjust.y=0;
00996 #endif
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 if ((args->unicode_array_len == 2)
01017 && (args->unicode_array[0] == (PL_FCI_MARK |0x004)))
01018 {
01019 adjust.x = args->just * ROUND (FT->face->glyph->metrics.width / 64.0);
01020 adjust.y = (FT_Pos) ROUND (FT->face->glyph->metrics.height / 128.0);
01021 }
01022 else
01023 {
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 adjust.y = (FT_Pos)
01035 ROUND (FT->face->size->metrics.height / height_factor / 128.0);
01036 adjust.x = (FT_Pos) (args->just * ROUND (w / 64.0));
01037
01038 }
01039
01040 FT_Vector_Transform( &adjust, &FT->matrix);
01041
01042 x-=adjust.x;
01043 y+=adjust.y;
01044
01045 FT_WriteStrW(pls,args->unicode_array,args->unicode_array_len,x,y);
01046 }
01047 else
01048 {
01049 plD_render_freetype_sym (pls, args);
01050 }
01051
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 void plD_FreeType_Destroy(PLStream *pls)
01063 {
01064 FT_Data *FT=(FT_Data *)pls->FT;
01065 extern int FT_Done_Library( FT_Library library );
01066
01067 if (FT) {
01068 if ((FT->smooth_text==1)&&(FT->BLENDED_ANTIALIASING==0)) plscmap0n(FT->ncol0_org);
01069 if (FT->textbuf)
01070 free(FT->textbuf);
01071 FT_Done_Library(FT->library);
01072 free(pls->FT);
01073 pls->FT=NULL;
01074 }
01075 }
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 static PLFLT CalculateIncrement( int bg, int fg, int levels)
01087 {
01088 PLFLT ret=0;
01089
01090 if (levels>1) {
01091 if (fg>bg)
01092 ret=((fg+1)-bg)/levels;
01093 else if (fg<bg)
01094 ret=(((fg-1)-bg)/levels);
01095 }
01096 return(ret);
01097 }
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114 void pl_set_extended_cmap0(PLStream *pls, int ncol0_width, int ncol0_org)
01115 {
01116 int i,j,k;
01117 int r,g,b;
01118 PLFLT r_inc,g_inc,b_inc;
01119
01120 for (i=1;i<ncol0_org;i++) {
01121
01122 r=pls->cmap0[i].r;
01123 g=pls->cmap0[i].g;
01124 b=pls->cmap0[i].b;
01125
01126 r_inc=CalculateIncrement(pls->cmap0[0].r,r,ncol0_width);
01127 g_inc=CalculateIncrement(pls->cmap0[0].g,g,ncol0_width);
01128 b_inc=CalculateIncrement(pls->cmap0[0].b,b,ncol0_width);
01129
01130 for (j=0,k=ncol0_org+i-1;j<ncol0_width;j++,k+=(ncol0_org-1)) {
01131 r-=r_inc;
01132 g-=g_inc;
01133 b-=b_inc;
01134 if ((r<0)||(g<0)||(b<0))
01135 plscol0 (k, 0, 0, 0);
01136 else
01137 plscol0 (k, (r > 0xff ? 0xff : r), (g > 0xff ? 0xff : g), (b > 0xff ? 0xff : b));
01138 }
01139 }
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 void plD_render_freetype_sym (PLStream *pls, EscText *args)
01156 {
01157 FT_Data *FT=(FT_Data *)pls->FT;
01158 int x,y;
01159 FT_Vector adjust;
01160 PLUNICODE fci;
01161
01162 if( FT->scale!=0.0 ) {
01163 x=args->x/FT->scale;
01164
01165 if (FT->invert_y==1)
01166 y=FT->ymax-(args->y/FT->scale);
01167 else
01168 y=args->y/FT->scale;
01169 } else {
01170 x=args->x/FT->scalex;
01171
01172 if (FT->invert_y==1)
01173 y=FT->ymax-(args->y/FT->scaley);
01174 else
01175 y=args->y/FT->scaley;
01176 }
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 #ifdef DODGIE_DECENDER_HACK
01196 adjust.y= (FT->face->descender >> 6)*3;
01197 #else
01198 adjust.y= (FT->face->descender >> 6);
01199 #endif
01200
01201 adjust.x=0;
01202 FT_Vector_Transform( &adjust, &FT->matrix);
01203 x+=adjust.x;
01204 y-=adjust.y;
01205
01206 plgfci(&fci);
01207 FT_SetFace(pls,fci);
01208
01209 FT=(FT_Data *)pls->FT;
01210 FT_Set_Transform( FT->face, &FT->matrix, &FT->pos );
01211
01212 FT_Load_Char( FT->face, args->unicode_char, (FT->smooth_text==0) ? FT_LOAD_MONOCHROME+FT_LOAD_RENDER : FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT );
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222 x -= (FT->face->glyph->advance.x >> 6)/2;
01223 FT_PlotChar(pls,FT, FT->face->glyph, x, y, pls->icol0 );
01224
01225 }
01226
01227
01228
01229
01230 #else
01231 int
01232 plfreetype()
01233 {
01234 return 0;
01235 }
01236
01237 #endif