draw9.c
0000/******************************************
0001 FreeType
0002******************************************/
0003#include <stdlib.h>
0004#include <string.h>
0005#include "draw6.h"
0006#include "draw7.h"
0007#include "draw8.h"
0008#include <ft2build.h>
0009#include FT_FREETYPE_H
0010#include <freetype/freetype.h>
0011#include <freetype/ftglyph.h>
0012#include <stdio.h>
0013#include <iconv.h>
0014
0015#define MAX_GLYPHS 80
0016
0017typedef struct TGlyph_
0018{
0019 FT_UInt index; /* glyph index */
0020 FT_Vector pos; /* glyph origin on the baseline */
0021 FT_Glyph image; /* glyph image */
0022} TGlyph, *PGlyph;
0023
0024FT_Library library=0; /* handle to library */
0025FT_Face face; /* handle to face object */
0026FT_GlyphSlot slot; /* a small shortcut */
0027
0028double position=0,ang=0;
0029double angle;
0030int sjis;
0031
0032void euc2sjis(unsigned char *c1,unsigned char *c2)
0033{
0034 if((*c1%2)==0) *c2-=0x02;
0035 else{
0036 *c2-=0x61;
0037 if(*c2>0x7e) ++*c2;
0038 }
0039 if(*c1<0xdf){
0040 ++*c1;
0041 *c1/=2;
0042 *c1+=0x30;
0043 }
0044 else{
0045 ++*c1;
0046 *c1/=2;
0047 *c1+=0x70;
0048 }
0049}
0050
0051int FDrawStr(char *c)
0052{
0053 TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */
0054 PGlyph glyph; /* current glyph in table */
0055 FT_UInt num_glyphs;
0056 FT_BBox bbox;
0057 int error;
0058 FT_Matrix matrix; /* transformation matrix */
0059 FT_Vector pen;
0060 FT_UInt glyph_index;
0061 FT_Bool use_kerning;
0062 FT_UInt previous;
0063 int pen_x, pen_y, n;
0064 int num_chars;
0065 int i,j,k;
0066 int string_width,string_height;
0067 int start_x,start_y;
0068 int left,top,right,bottom,startx,starty,middlex,middley,endx,endy;
0069 int left1,top1,right1,bottom1,startx1,starty1,middlex1,middley1,endx1,endy1;
0070 double x,y,x1,y1;
0071 int wid,hei;
0072 PixMap *p;
0073 unsigned char *pc;
0074 FT_Vector start;
0075 unsigned char c1,c2;
0076 char s[300];
0077 iconv_t cd;
0078 char *s2;
0079 char *s3;
0080
0081 /*** 0th phase : convert UTF-8 to EUC-JP ***/
0082 if(sjis){
0083 // cd=iconv_open("EUC-JP","UTF-8");
0084 cd=iconv_open("UTF16BE","UTF-8");
0085 s2=c;
0086 s3=s;
0087 i=strlen(c);
0088 j=299;
0089 iconv(cd,&s2,&i,&s3,&j);
0090 iconv_close(cd);
0091 s[299-j]='\0';
0092 }
0093
0094 /*** 1st phase : get pixbuf size ***/
0095 pen_x=0; /* start at (0,0)! */
0096 pen_y=0;
0097
0098 num_glyphs=0;
0099 use_kerning=FT_HAS_KERNING( face );
0100
0101 previous=0;
0102
0103 if(sjis){
0104 num_chars=strlen(s);
0105 num_chars/=2;
0106 }
0107 else num_chars=strlen(c);
0108
0109 glyph = glyphs;
0110 for(n=0;n<num_chars;n++){
0111 if(sjis){
0112 i=0;
0113 c1=*((unsigned char *)s+2*n);
0114 c2=*((unsigned char *)s+2*n+1);
0115 // euc2sjis(&c1,&c2);
0116 *(unsigned char *)(&i)=c2;
0117 *((unsigned char *)(&i)+1)=c1;
0118 }
0119 else i=c[n];
0120 glyph->index=FT_Get_Char_Index(face,i);
0121
0122 if ( use_kerning && previous && glyph->index ){
0123 FT_Vector delta;
0124 FT_Get_Kerning(face,previous, glyph->index,
0125 ft_kerning_default,&delta);
0126 pen_x+=delta.x>>6;
0127 }
0128
0129 /* store current pen position */
0130 glyph->pos.x=pen_x*64;
0131 glyph->pos.y=pen_y*64;
0132
0133
0134 /* load glyph image into the slot. DO NOT RENDER IT! */
0135 error=FT_Load_Glyph(face,glyph->index,FT_LOAD_DEFAULT);
0136 if(error) continue; /* ignore errors, jump to next glyph */
0137
0138 /* extract glyph image and store it in our table */
0139 error=FT_Get_Glyph(face->glyph,&glyph->image);
0140 if(error) continue; /* ignore errors, jump to next glyph */
0141
0142 /* translate the glyph image now */
0143 FT_Glyph_Transform(glyph->image,0,&glyph->pos);
0144
0145 pen_x+=slot->advance.x>>6;
0146 previous=glyph->index;
0147
0148 /* increment number of glyphs */
0149 glyph++;
0150 }
0151 /* count number of glyphs loaded */
0152 num_glyphs=glyph-glyphs;
0153
0154 /* initialize string bbox to "empty" values */
0155 bbox.xMin=bbox.yMin= 32000;
0156 bbox.xMax=bbox.yMax=-32000;
0157
0158 /* for each glyph image, compute its bounding box, */
0159
0160 for(n=0;n<num_glyphs;n++){
0161 FT_BBox glyph_bbox;
0162 FT_Glyph_Get_CBox( glyphs[n].image,ft_glyph_bbox_pixels, &glyph_bbox );
0163 if(glyph_bbox.xMin<bbox.xMin)
0164 bbox.xMin=glyph_bbox.xMin;
0165 if(glyph_bbox.yMin<bbox.yMin)
0166 bbox.yMin=glyph_bbox.yMin;
0167 if(glyph_bbox.xMax>bbox.xMax)
0168 bbox.xMax=glyph_bbox.xMax;
0169 if(glyph_bbox.yMax>bbox.yMax)
0170 bbox.yMax=glyph_bbox.yMax;
0171 }
0172 /* check that we really grew the string bbox */
0173 if(bbox.xMin>bbox.xMax){
0174 bbox.xMin=0;
0175 bbox.yMin=0;
0176 bbox.xMax=0;
0177 bbox.yMax=0;
0178 }
0179
0180 /* compute string dimensions in integer pixels */
0181 left1=bottom1=32000;
0182 top1=right1=-32000;
0183 x=bbox.xMin;
0184 y=bbox.yMax;
0185 i=x*cos(angle)-y*sin(angle);
0186 j=x*sin(angle)+y*cos(angle);
0187 if(i<left1) left1=i;
0188 if(i>right1) right1=i;
0189 if(j<bottom1) bottom1=j;
0190 if(j>top1) top1=j;
0191 x=bbox.xMin;
0192 y=bbox.yMin;
0193 i=x*cos(angle)-y*sin(angle);
0194 j=x*sin(angle)+y*cos(angle);
0195 if(i<left1) left1=i;
0196 if(i>right1) right1=i;
0197 if(j<bottom1) bottom1=j;
0198 if(j>top1) top1=j;
0199 x=bbox.xMax;
0200 y=bbox.yMin;
0201 i=x*cos(angle)-y*sin(angle);
0202 j=x*sin(angle)+y*cos(angle);
0203 if(i<left1) left1=i;
0204 if(i>right1) right1=i;
0205 if(j<bottom1) bottom1=j;
0206 if(j>top1) top1=j;
0207 x=bbox.xMax;
0208 y=bbox.yMax;
0209 i=x*cos(angle)-y*sin(angle);
0210 j=x*sin(angle)+y*cos(angle);
0211 if(i<left1) left1=i;
0212 if(i>right1) right1=i;
0213 if(j<bottom1) bottom1=j;
0214 if(j>top1) top1=j;
0215
0216 wid=right1-left1+4;
0217 hei=top1-bottom1+4;
0218 startx=-left1+2; /* (0,0) transformed */
0219 starty=top1+2;
0220 x=bbox.xMax;
0221 y=0.;
0222 i=x*cos(angle)-y*sin(angle);
0223 j=x*sin(angle)+y*cos(angle);
0224 endx=i-left1+2;
0225 endy=top1-j+2;
0226
0227 p=pcreate(2,wid,hei); /* 8-bit grayscale */
0228 j=wid*hei;
0229 for(i=0;i<j;i++)
0230 p->pixdata[i]=0;
0231 if(position==0){
0232 p->refx=startx;
0233 p->refy=starty;
0234 }
0235 else{
0236 p->refx=startx+(endx-startx)/position;
0237 p->refy=starty+(endy-starty)/position;
0238 }
0239
0240 /*** Step 2 pixel buffer created, now draw on it ***/
0241 /* compute start pen position in 26.6 cartesian pixels */
0242 start.x = startx * 64;
0243 start.y = (hei-starty) * 64;
0244 /* set up transformation (a rotation here) */
0245 matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
0246 matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
0247 matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
0248 matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
0249
0250 for ( n = 0; n < num_glyphs; n++ ){
0251 FT_Glyph image;
0252 FT_Vector pen;
0253
0254 /* create a copy of the original glyph */
0255 error = FT_Glyph_Copy( glyphs[n].image, &image );
0256 if ( error ) continue;
0257
0258 /* transform copy (this will also translate it to the */
0259 /* correct position */
0260 FT_Glyph_Transform( image, &matrix, &start );
0261// FT_Glyph_Transform( image, &matrix, 0 );
0262
0263 /* check bounding box -- if the transformed glyph image */
0264 /* is not in our target surface, we can avoid rendering */
0265 FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
0266
0267 if ( bbox.xMax <= 0 || bbox.xMin >= wid ||
0268 bbox.yMax <= 0 || bbox.yMin >= hei )
0269 continue;
0270
0271 /* convert glyph image to bitmap (destroy the glyph */
0272 /* copy!) */
0273 error = FT_Glyph_To_Bitmap(
0274 &image,
0275 ft_render_mode_normal,
0276 0, /* no additional translation */
0277 1 ); /* destroy copy in "image" */
0278 if ( !error ){
0279 FT_BitmapGlyph bit = (FT_BitmapGlyph)image;
0280
0281 k=0;
0282 for(j=0;j<bit->bitmap.rows;j++)
0283 for(i=0;i<bit->bitmap.width;i++)
0284 if(bit->bitmap.buffer[k]!=0)
0285 p->pixdata[bit->left+i+wid*(hei-bit->top+j)]=bit->bitmap.buffer[k++];
0286 else k++;
0287
0288 FT_Done_Glyph( image );
0289 }
0290 }
0291 j=MakePixmap(2,wid,hei);
0292 XferPixmap(j,p);
0293 PastePixmap(j,0,0,3);
0294 DestroyPixmap(j);
0295 pdestroy(p);
0296 return 0;
0297}
0298
0299int FDrawStrSize(char *c,int *wid,int *asc,int *dec)
0300{
0301 TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */
0302 PGlyph glyph; /* current glyph in table */
0303 FT_UInt num_glyphs;
0304 FT_BBox bbox;
0305 int error;
0306 FT_UInt glyph_index;
0307 FT_Bool use_kerning;
0308 FT_UInt previous;
0309 int pen_x, pen_y, n;
0310 int num_chars;
0311 int i,j,k;
0312 int string_width,string_height;
0313 int target_width,target_height;
0314 int start_x,start_y;
0315 unsigned char c1,c2;
0316 char s[300];
0317 iconv_t cd;
0318 char *s2;
0319 char *s3;
0320
0321 /*** 0th phase : convert UTF-8 to EUC-JP ***/
0322 if(sjis){
0323 cd=iconv_open("UTF16BE","UTF-8");
0324 s2=c;
0325 s3=s;
0326 i=strlen(c);
0327 j=299;
0328 iconv(cd,&s2,&i,&s3,&j);
0329 iconv_close(cd);
0330 s[299-j]='\0';
0331 }
0332
0333 pen_x=0; /* start at (0,0)! */
0334 pen_y=0;
0335
0336 num_glyphs=0;
0337 use_kerning=FT_HAS_KERNING( face );
0338
0339 previous=0;
0340
0341 if(sjis){
0342 num_chars=strlen(s);
0343 num_chars/=2;
0344 }
0345 else num_chars=strlen(c);
0346
0347 glyph = glyphs;
0348 for(n=0;n<num_chars;n++){
0349 if(sjis){
0350 c1=*((unsigned char *)s+2*n);
0351 c2=*((unsigned char *)s+2*n+1);
0352 // euc2sjis(&c1,&c2);
0353 *(unsigned char *)(&i)=c2;
0354 *((unsigned char *)(&i)+1)=c1;
0355 }
0356 else i=c[n];
0357 glyph->index=FT_Get_Char_Index(face,i);
0358
0359 if ( use_kerning && previous && glyph->index ){
0360 FT_Vector delta;
0361 FT_Get_Kerning(face,previous, glyph->index,
0362 ft_kerning_default,&delta);
0363 pen_x+=delta.x>>6;
0364 }
0365
0366 /* store current pen position */
0367 glyph->pos.x=pen_x*64;
0368 glyph->pos.y=pen_y*64;
0369
0370
0371 /* load glyph image into the slot. DO NOT RENDER IT! */
0372 error=FT_Load_Glyph(face,glyph->index,FT_LOAD_DEFAULT);
0373 if(error) continue; /* ignore errors, jump to next glyph */
0374
0375 /* extract glyph image and store it in our table */
0376 error=FT_Get_Glyph(face->glyph,&glyph->image);
0377 if(error) continue; /* ignore errors, jump to next glyph */
0378
0379 /* translate the glyph image now */
0380 FT_Glyph_Transform(glyph->image,0,&glyph->pos);
0381
0382 pen_x+=slot->advance.x>>6;
0383 previous=glyph->index;
0384
0385 /* increment number of glyphs */
0386 glyph++;
0387 }
0388 /* count number of glyphs loaded */
0389 num_glyphs=glyph-glyphs;
0390
0391 /* initialize string bbox to "empty" values */
0392 bbox.xMin=bbox.yMin= 32000;
0393 bbox.xMax=bbox.yMax=-32000;
0394
0395 /* for each glyph image, compute its bounding box, */
0396
0397 for(n=0;n<num_glyphs;n++){
0398 FT_BBox glyph_bbox;
0399 FT_Glyph_Get_CBox( glyphs[n].image,ft_glyph_bbox_pixels, &glyph_bbox );
0400 if(glyph_bbox.xMin<bbox.xMin)
0401 bbox.xMin=glyph_bbox.xMin;
0402 if(glyph_bbox.yMin<bbox.yMin)
0403 bbox.yMin=glyph_bbox.yMin;
0404 if(glyph_bbox.xMax>bbox.xMax)
0405 bbox.xMax=glyph_bbox.xMax;
0406 if(glyph_bbox.yMax>bbox.yMax)
0407 bbox.yMax=glyph_bbox.yMax;
0408 }
0409 /* check that we really grew the string bbox */
0410 if(bbox.xMin>bbox.xMax){
0411 bbox.xMin=0;
0412 bbox.yMin=0;
0413 bbox.xMax=0;
0414 bbox.yMax=0;
0415 }
0416
0417 /* compute string dimensions in integer pixels */
0418 *wid=bbox.xMax-bbox.xMin;
0419 *asc=bbox.yMax;
0420 *dec=-bbox.yMin;
0421 return 0;
0422}
0423
0424/***********************************************************************
0425 FSetFont
0426
0427 font: 0 usrX11R6libX11fontsType1UTBI____.pfa
0428 1 usrX11R6libX11fontsType1UTB_____.pfa
0429 2 usrX11R6libX11fontsType1UTI_____.pfa
0430 3 usrX11R6libX11fontsType1UTRG____.pfa
0431 4 usrX11R6libX11fontsType1cour.pfa
0432 5 usrX11R6libX11fontsType1courb.pfa
0433 6 usrX11R6libX11fontsType1courbi.pfa
0434 7 usrX11R6libX11fontsType1couri.pfa
0435 8 usrX11R6libX11fontsType1lcdxmo.pfa
0436 9 usrX11R6libX11fontsType1lcdxmr.pfa
0437 10 usrX11R6libX11fontsType1lcdxro.pfa
0438 11 usrX11R6libX11fontsType1lcdxrr.pfa
0439 12 usrX11R6libX11fontsType1lcdxso.pfa
0440 13 usrX11R6libX11fontsType1lcdxsr.pfa
0441 14 usrsharefontsjaTrueTypewatanabe-mincho.ttf
0442 15 usrsharefontsjaTrueTypewadalab-gothic.ttf
0443 direc:
0444 direc=angle*100+position
0445 Angle is 0 for the normal horizontal string, and measured
0446 in degree counter-clockwise.
0447 It can be specified with a digit below decimal point.
0448 Position is either
0449 0 : current pen position is at the left side of the string
0450 1 : current pen position is at the right side of the string or
0451 2 : current pen position is at the middle of the string.
0452 size: character height in pixel
0453***********************************************************************/
0454int FSetFont(int font,int direc,int size)
0455{
0456// char *ff[]={"UTBI____.pfa","UTB_____.pfa","UTI_____.pfa","UTRG____.pfa",
0457// "cour.pfa","courb.pfa","courbi.pfa","couri.pfa",
0458// "lcdxmo.pfa","lcdxmr.pfa","lcdxro.pfa","lcdxrr.pfa",
0459// "lcdxso.pfa","lcdxsr.pfa","watanabe-mincho.ttf","wadalab-gothic.ttf"};
0460// char *fd[]={"/usr/X11R6/lib/X11/fonts/Type1/","/usr/share/fonts/ja/TrueType/"};
0461 char *ff[]={"UTBI____.pfa","UTB_____.pfa","UTI_____.pfa","UTRG____.pfa",
0462 "cour.pfa","courb.pfa","courbi.pfa","couri.pfa",
0463 "l047033t.pfa","l047013t.pfa","l049033t.pfa","l049013t.pfa",
0464 "l048033t.pfa","l048013t.pfa","kochi-mincho-subst.ttf","kochi-gothic-subst.ttf"};
0465 char *fd[]={"/usr/X11R6/lib/X11/fonts/Type1/","/usr/share/fonts/japanese/TrueType/"};
0466 char file[100];
0467 int i;
0468
0469 if(font<14){
0470 strcpy(file,fd[0]);
0471 sjis=0;
0472 }
0473 else if(font<16){
0474 strcpy(file,fd[1]);
0475 sjis=1;
0476 }
0477 else return 1;
0478 strcat(file,ff[font]);
0479
0480 if(library==0) FT_Init_FreeType(&library);
0481 FT_New_Face(library,file,0,&face);
0482 if(font<14){
0483 i=strlen(file);
0484 strcpy(&file[i-3],"afm");
0485 FT_Attach_File(face,file);
0486 }
0487
0488 if(sjis) FT_Select_Charmap(face,ft_encoding_sjis);
0489 FT_Set_Pixel_Sizes(face,0,size);
0490 slot = face->glyph;
0491 position=direc%10;
0492 ang=direc-position;
0493 ang/=100.;
0494 angle=ang*0.017453;
0495}
0496
0497int fttest()
0498{
0499 FSetFont(8,3001,40);
0500 FDrawStr("abcdefghi");
0501 return 0;
0502}
0503