GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
text3.c
Go to the documentation of this file.
1 /* text draw truetypefont
2  *
3  * 2004/01/30
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <grass/config.h>
10 #ifdef HAVE_ICONV_H
11 #include <iconv.h>
12 #endif
13 
14 #ifdef HAVE_FT2BUILD_H
15 #include <ft2build.h>
16 #include FT_FREETYPE_H
17 #endif
18 
19 #include <grass/gis.h>
20 #include "driver.h"
21 #include "driverlib.h"
22 
23 # define RpD ((2 * M_PI) / 360.) /* radians/degree */
24 # define D2R(d) (double)(d * RpD) /* degrees->radians */
25 
26 /*#define DEBUG_LOG(S) {FILE *fp = fopen("debug.TXT","a");fputs(S,fp);fclose(fp);} */
27 /*#define DEBUG_LOG_INT(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);} */
28 /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);} */
29 
30 #ifdef HAVE_FT2BUILD_H
31 static int convert_str(const char *, const char *, unsigned char **);
32 static void release_convert_str(unsigned char *);
33 static void set_matrix(FT_Matrix *, double);
34 static void draw_text(FT_Face, FT_Vector *, FT_Matrix *,
35  const unsigned char *, int, int);
36 static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
37 static void set_text_box(FT_Bitmap *, FT_Int, FT_Int);
38 #endif
39 
40 static int fdont_draw = 0;
41 static int ft, fb, fl, fr;
42 
43 static void draw_main(int x, int y,
44  double text_size_x, double text_size_y,
45  double text_rotation, const char *string)
46 {
47 #ifdef HAVE_FT2BUILD_H
48  FT_Library library;
49  FT_Face face;
50  FT_Matrix matrix;
51 
52  /*FT_UInt glyph_index; */
53  FT_Vector pen;
54  FT_Error ans;
55  const char *filename;
56  const char *charset;
57  int font_index;
58  unsigned char *out;
59  int outlen;
60 
61  /* get file name */
62  filename = font_get_freetype_name();
63  charset = font_get_charset();
64  font_index = font_get_index();
65 
66  /* set freetype */
67  ans = FT_Init_FreeType(&library);
68  if (ans) {
69  /* DEBUG_LOG("Text3 error: ft init\n"); */
70  return;
71  }
72  ans = FT_New_Face(library, filename, font_index, &face);
73  if (ans == FT_Err_Unknown_File_Format) {
74  /* DEBUG_LOG("Text3 error: ft new face 1\n"); */
75  FT_Done_FreeType(library);
76  return;
77  }
78  else if (ans) {
79  /* DEBUG_LOG("Text3 error: ft new face 2\n"); */
80  FT_Done_FreeType(library);
81  return;
82  }
83 
84  /* ans = FT_Set_Pixel_Sizes(face,10,10); */
85  /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,0,0); */
86  /* ans = FT_Set_Char_Size(face,10*64,0,72,0); */
87  /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,72,72); */
88  ans =
89  FT_Set_Char_Size(face, (int)(text_size_x * 64),
90  (int)(text_size_y * 64), 100, 100);
91  /*
92  ans = FT_Set_Pixel_Sizes(
93  face,
94  0,
95  (int)text_size_y );
96  */
97  if (ans) {
98  /* DEBUG_LOG("Text3 error: ft set size\n"); */
99  FT_Done_Face(face);
100  FT_Done_FreeType(library);
101  return;
102  }
103 
104  /* init point */
105  pen.x = x * 64;
106  /* pen.y = 0; */
107  pen.y = (screen_bottom - y) * 64;
108 
109  /* convert string to:shift-jis from:charset */
110  outlen = convert_str(charset, string, &out);
111 
112  /* set matrix */
113  set_matrix(&matrix, D2R(text_rotation));
114  /* draw */
115  draw_text(face, &pen, &matrix, out, outlen, 0);
116 
117  /* release */
118  release_convert_str(out);
119 
120  /* FT_done */
121  FT_Done_Face(face);
122  FT_Done_FreeType(library);
123 #endif
124 }
125 
126 #ifdef HAVE_FT2BUILD_H
127 static void set_matrix(FT_Matrix * matrix, double rotation)
128 {
129  /* rotation is in radians */
130  matrix->xx = (FT_Fixed) (cos(rotation) * 0x10000);
131  matrix->xy = (FT_Fixed) (-sin(rotation) * 0x10000);
132  matrix->yx = (FT_Fixed) (sin(rotation) * 0x10000);
133  matrix->yy = (FT_Fixed) (cos(rotation) * 0x10000);
134 }
135 
136 static int convert_str(const char *from, const char *in, unsigned char **out)
137 {
138  size_t len, i, res;
139  const unsigned char *p1;
140  unsigned char *p2;
141 
142  len = strlen(in);
143  res = 2 * (len + 1);
144 
145  *out = G_calloc(1, res);
146  p1 = in;
147  p2 = *out;
148 
149 #ifdef HAVE_ICONV_H
150  {
151  size_t ret;
152  iconv_t cd;
153 
154  i = res;
155  if ((cd = iconv_open("UCS-2BE", from)) < 0)
156  return -1;
157  ret = iconv(cd, (char **)&p1, &len, (char **)&p2, &i);
158  iconv_close(cd);
159 
160  res -= i;
161  }
162 #else
163  for (i = 0; i <= len; i++)
164  /* Pad each character out to 2 bytes, i.e. UCS-2 Big Endian encoding
165  * (note low byte has already been zeroed by G_calloc() call) */
166  p2[2 * i + 1] = p1[i];
167 
168  res = 2 * len;
169 #endif
170 
171  return res;
172 }
173 
174 static void release_convert_str(unsigned char *out)
175 {
176  G_free(out);
177 }
178 
179 static void draw_text(FT_Face face, FT_Vector * pen, FT_Matrix * matrix,
180  const unsigned char *out, int len, int color)
181 {
182  FT_ULong ch;
183  FT_Error ans;
184  FT_GlyphSlot slot = face->glyph;
185  int i;
186 
187  for (i = 0; i < len; i += 2) {
188  ch = (out[i] << 8) | out[i + 1];
189  if (ch == 10)
190  continue;
191  /* transform */
192  FT_Set_Transform(face, matrix, pen);
193  /* get glyph image */
194  ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP);
195  if (ans)
196  continue;
197  ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
198  if (ans)
199  continue;
200  /* draw bitmap */
201  if (!fdont_draw)
202  draw_bitmap(&slot->bitmap, slot->bitmap_left,
203  screen_bottom - slot->bitmap_top);
204  else
205  set_text_box(&slot->bitmap, slot->bitmap_left,
206  screen_bottom - slot->bitmap_top);
207 
208  /* increment pen position */
209  pen->x += slot->advance.x;
210  pen->y += slot->advance.y;
211  }
212 }
213 
214 static void set_text_box(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
215 {
216  FT_Int xMax = x + bitmap->width;
217  FT_Int yMax = y + bitmap->rows;
218 
219  if ((x == xMax) || (y == yMax))
220  return;
221  if (x < fl)
222  fl = x;
223  if (xMax > fr)
224  fr = xMax;
225  if (y < ft)
226  ft = y;
227  if (yMax > fb)
228  fb = yMax;
229 }
230 
231 static void draw_bitmap(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
232 {
233  static unsigned char *buf;
234  static int nalloc;
235  int w, h;
236  int bw = bitmap->width;
237  int bh = bitmap->rows;
238  const unsigned char *sbuf = bitmap->buffer;
239  int offset, i, j;
240  double x1, y1, x2, y2;
241 
242  x1 = (double)x;
243  y1 = (double)y;
244  x2 = x1 + (double)bw;
245  y2 = y1 + (double)bh;
246 
247  w = x2 - x1;
248  h = y2 - y1;
249  if (w <= 0 || h <= 0)
250  return;
251 
252  offset = ((int)y1 - y) * bw + (int)x1 - x;
253 
254  if (nalloc < w * h) {
255  nalloc = w * h;
256  buf = G_realloc(buf, nalloc);
257  }
258 
259  for (j = 0; j < h; j++)
260  for (i = 0; i < w; i++)
261  buf[j * w + i] = sbuf[offset + j * bw + i];
262 
263  COM_Move_abs(x1, y1);
264  DRV_draw_bitmap(w, h, 128, buf);
265 }
266 #endif
267 
268 void soft_text_freetype(int x, int y,
269  double text_size_x, double text_size_y,
270  double text_rotation, const char *string)
271 {
272  text_size_x *= 25.0;
273  text_size_y *= 25.0;
274  draw_main(x, y, text_size_x, text_size_y, text_rotation, string);
275 }
276 
277 void soft_text_ext_freetype(int x, int y,
278  double text_size_x, double text_size_y,
279  double text_rotation, const char *string)
280 {
281  fdont_draw = 1;
282  text_size_x *= 25.0;
283  text_size_y *= 25.0;
284  ft = 999999;
285  fb = 0;
286  fl = 999999;
287  fr = 0;
288  /* draw_main(x,y,text_size_x,text_size_y,text_rotation,string); */
289  /* draw_main(0,0,text_size_x,text_size_y,text_rotation,string); */
290  draw_main(0, y, text_size_x, text_size_y, text_rotation, string);
291  /* ft += y; */
292  /* fb += y; */
293  fl += x;
294  fr += x;
295  fdont_draw = 0;
296 }
297 
298 void get_text_ext_freetype(int *top, int *bot, int *left, int *rite)
299 {
300  *top = ft;
301  *bot = fb;
302  *left = fl;
303  *rite = fr;
304 }
double text_size_y
Definition: driver/init.c:41
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
void COM_Move_abs(int, int)
Definition: Move.c:4
void get_text_ext_freetype(int *, int *, int *, int *)
Definition: text3.c:298
#define D2R(d)
Definition: text3.c:24
void DRV_draw_bitmap(int ncols, int nrows, int threshold, const unsigned char *buf)
Definition: Draw.c:5
const char * font_get_charset(void)
Definition: font_freetype.c:34
int y
Definition: plot.c:34
double text_rotation
Definition: driver/init.c:42
double text_size_x
Definition: driver/init.c:40
const char * font_get_freetype_name(void)
Definition: font_freetype.c:29
tuple color
Definition: tools.py:1703
int
Definition: g3dcolor.c:48
void soft_text_freetype(int, int, double, double, double, const char *)
Definition: text3.c:268
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int screen_bottom
Definition: driver/init.c:34
int font_get_index(void)
Definition: font_freetype.c:41
void soft_text_ext_freetype(int, int, double, double, double, const char *)
Definition: text3.c:277
tuple h
panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _(&quot;Use default size&quot;)) panel...