GRASS Programmer's Manual  6.4.2(2012)
text3.c
Go to the documentation of this file.
00001 /* text draw truetypefont
00002  *
00003  * 2004/01/30
00004  */
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <math.h>
00009 #include <grass/config.h>
00010 #ifdef HAVE_ICONV_H
00011 #include <iconv.h>
00012 #endif
00013 
00014 #ifdef HAVE_FT2BUILD_H
00015 #include <ft2build.h>
00016 #include FT_FREETYPE_H
00017 #endif
00018 
00019 #include <grass/gis.h>
00020 #include "driver.h"
00021 #include "driverlib.h"
00022 
00023 # define RpD ((2 * M_PI) / 360.)        /* radians/degree */
00024 # define D2R(d) (double)(d * RpD)       /* degrees->radians */
00025 
00026 /*#define DEBUG_LOG(S) {FILE *fp = fopen("debug.TXT","a");fputs(S,fp);fclose(fp);} */
00027 /*#define DEBUG_LOG_INT(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);} */
00028 /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);} */
00029 
00030 #ifdef HAVE_FT2BUILD_H
00031 static int convert_str(const char *, const char *, unsigned char **);
00032 static void release_convert_str(unsigned char *);
00033 static void set_matrix(FT_Matrix *, double);
00034 static void draw_text(FT_Face, FT_Vector *, FT_Matrix *,
00035                       const unsigned char *, int, int);
00036 static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
00037 static void set_text_box(FT_Bitmap *, FT_Int, FT_Int);
00038 #endif
00039 
00040 static int fdont_draw = 0;
00041 static int ft, fb, fl, fr;
00042 
00043 static void draw_main(int x, int y,
00044                       double text_size_x, double text_size_y,
00045                       double text_rotation, const char *string)
00046 {
00047 #ifdef HAVE_FT2BUILD_H
00048     FT_Library library;
00049     FT_Face face;
00050     FT_Matrix matrix;
00051 
00052     /*FT_UInt glyph_index; */
00053     FT_Vector pen;
00054     FT_Error ans;
00055     const char *filename;
00056     const char *charset;
00057     int font_index;
00058     unsigned char *out;
00059     int outlen;
00060 
00061     /* get file name */
00062     filename = font_get_freetype_name();
00063     charset = font_get_charset();
00064     font_index = font_get_index();
00065 
00066     /* set freetype */
00067     ans = FT_Init_FreeType(&library);
00068     if (ans) {
00069         /* DEBUG_LOG("Text3 error: ft init\n"); */
00070         return;
00071     }
00072     ans = FT_New_Face(library, filename, font_index, &face);
00073     if (ans == FT_Err_Unknown_File_Format) {
00074         /* DEBUG_LOG("Text3 error: ft new face 1\n"); */
00075         FT_Done_FreeType(library);
00076         return;
00077     }
00078     else if (ans) {
00079         /* DEBUG_LOG("Text3 error: ft new face 2\n"); */
00080         FT_Done_FreeType(library);
00081         return;
00082     }
00083 
00084     /* ans = FT_Set_Pixel_Sizes(face,10,10); */
00085     /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,0,0); */
00086     /* ans = FT_Set_Char_Size(face,10*64,0,72,0); */
00087     /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,72,72); */
00088     ans =
00089         FT_Set_Char_Size(face, (int)(text_size_x * 64),
00090                          (int)(text_size_y * 64), 100, 100);
00091     /*
00092        ans = FT_Set_Pixel_Sizes(
00093        face,
00094        0,
00095        (int)text_size_y );
00096      */
00097     if (ans) {
00098         /* DEBUG_LOG("Text3 error: ft set size\n"); */
00099         FT_Done_Face(face);
00100         FT_Done_FreeType(library);
00101         return;
00102     }
00103 
00104     /* init point */
00105     pen.x = x * 64;
00106     /* pen.y = 0; */
00107     pen.y = (screen_bottom - y) * 64;
00108 
00109     /* convert string to:shift-jis from:charset */
00110     outlen = convert_str(charset, string, &out);
00111 
00112     /* set matrix */
00113     set_matrix(&matrix, D2R(text_rotation));
00114     /* draw */
00115     draw_text(face, &pen, &matrix, out, outlen, 0);
00116 
00117     /* release */
00118     release_convert_str(out);
00119 
00120     /* FT_done */
00121     FT_Done_Face(face);
00122     FT_Done_FreeType(library);
00123 #endif
00124 }
00125 
00126 #ifdef HAVE_FT2BUILD_H
00127 static void set_matrix(FT_Matrix * matrix, double rotation)
00128 {
00129     /* rotation is in radians */
00130     matrix->xx = (FT_Fixed) (cos(rotation) * 0x10000);
00131     matrix->xy = (FT_Fixed) (-sin(rotation) * 0x10000);
00132     matrix->yx = (FT_Fixed) (sin(rotation) * 0x10000);
00133     matrix->yy = (FT_Fixed) (cos(rotation) * 0x10000);
00134 }
00135 
00136 static int convert_str(const char *from, const char *in, unsigned char **out)
00137 {
00138     size_t len, i, res;
00139     const unsigned char *p1;
00140     unsigned char *p2;
00141 
00142     len = strlen(in);
00143     res = 2 * (len + 1);
00144 
00145     *out = G_calloc(1, res);
00146     p1 = in;
00147     p2 = *out;
00148 
00149 #ifdef HAVE_ICONV_H
00150     {
00151         size_t ret;
00152         iconv_t cd;
00153 
00154         i = res;
00155         if ((cd = iconv_open("UCS-2BE", from)) < 0)
00156             return -1;
00157         ret = iconv(cd, (char **)&p1, &len, (char **)&p2, &i);
00158         iconv_close(cd);
00159 
00160         res -= i;
00161     }
00162 #else
00163     for (i = 0; i <= len; i++)
00164         /* Pad each character out to 2 bytes, i.e. UCS-2 Big Endian encoding
00165          * (note low byte has already been zeroed by G_calloc() call) */
00166         p2[2 * i + 1] = p1[i];
00167 
00168     res = 2 * len;
00169 #endif
00170 
00171     return res;
00172 }
00173 
00174 static void release_convert_str(unsigned char *out)
00175 {
00176     G_free(out);
00177 }
00178 
00179 static void draw_text(FT_Face face, FT_Vector * pen, FT_Matrix * matrix,
00180                       const unsigned char *out, int len, int color)
00181 {
00182     FT_ULong ch;
00183     FT_Error ans;
00184     FT_GlyphSlot slot = face->glyph;
00185     int i;
00186 
00187     for (i = 0; i < len; i += 2) {
00188         ch = (out[i] << 8) | out[i + 1];
00189         if (ch == 10)
00190             continue;
00191         /* transform */
00192         FT_Set_Transform(face, matrix, pen);
00193         /* get glyph image */
00194         ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP);
00195         if (ans)
00196             continue;
00197         ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
00198         if (ans)
00199             continue;
00200         /* draw bitmap */
00201         if (!fdont_draw)
00202             draw_bitmap(&slot->bitmap, slot->bitmap_left,
00203                         screen_bottom - slot->bitmap_top);
00204         else
00205             set_text_box(&slot->bitmap, slot->bitmap_left,
00206                          screen_bottom - slot->bitmap_top);
00207 
00208         /* increment pen position */
00209         pen->x += slot->advance.x;
00210         pen->y += slot->advance.y;
00211     }
00212 }
00213 
00214 static void set_text_box(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
00215 {
00216     FT_Int xMax = x + bitmap->width;
00217     FT_Int yMax = y + bitmap->rows;
00218 
00219     if ((x == xMax) || (y == yMax))
00220         return;
00221     if (x < fl)
00222         fl = x;
00223     if (xMax > fr)
00224         fr = xMax;
00225     if (y < ft)
00226         ft = y;
00227     if (yMax > fb)
00228         fb = yMax;
00229 }
00230 
00231 static void draw_bitmap(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
00232 {
00233     static unsigned char *buf;
00234     static int nalloc;
00235     int w, h;
00236     int bw = bitmap->width;
00237     int bh = bitmap->rows;
00238     const unsigned char *sbuf = bitmap->buffer;
00239     int offset, i, j;
00240     double x1, y1, x2, y2;
00241 
00242     x1 = (double)x;
00243     y1 = (double)y;
00244     x2 = x1 + (double)bw;
00245     y2 = y1 + (double)bh;
00246 
00247     w = x2 - x1;
00248     h = y2 - y1;
00249     if (w <= 0 || h <= 0)
00250         return;
00251 
00252     offset = ((int)y1 - y) * bw + (int)x1 - x;
00253 
00254     if (nalloc < w * h) {
00255         nalloc = w * h;
00256         buf = G_realloc(buf, nalloc);
00257     }
00258 
00259     for (j = 0; j < h; j++)
00260         for (i = 0; i < w; i++)
00261             buf[j * w + i] = sbuf[offset + j * bw + i];
00262 
00263     COM_Move_abs(x1, y1);
00264     DRV_draw_bitmap(w, h, 128, buf);
00265 }
00266 #endif
00267 
00268 void soft_text_freetype(int x, int y,
00269                         double text_size_x, double text_size_y,
00270                         double text_rotation, const char *string)
00271 {
00272     text_size_x *= 25.0;
00273     text_size_y *= 25.0;
00274     draw_main(x, y, text_size_x, text_size_y, text_rotation, string);
00275 }
00276 
00277 void soft_text_ext_freetype(int x, int y,
00278                             double text_size_x, double text_size_y,
00279                             double text_rotation, const char *string)
00280 {
00281     fdont_draw = 1;
00282     text_size_x *= 25.0;
00283     text_size_y *= 25.0;
00284     ft = 999999;
00285     fb = 0;
00286     fl = 999999;
00287     fr = 0;
00288     /* draw_main(x,y,text_size_x,text_size_y,text_rotation,string); */
00289     /* draw_main(0,0,text_size_x,text_size_y,text_rotation,string); */
00290     draw_main(0, y, text_size_x, text_size_y, text_rotation, string);
00291     /* ft += y; */
00292     /* fb += y; */
00293     fl += x;
00294     fr += x;
00295     fdont_draw = 0;
00296 }
00297 
00298 void get_text_ext_freetype(int *top, int *bot, int *left, int *rite)
00299 {
00300     *top = ft;
00301     *bot = fb;
00302     *left = fl;
00303     *rite = fr;
00304 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines