GRASS Programmer's Manual
6.4.2(2012)
|
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 }