GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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 DEBUG_LOG(S) {FILE *fp = fopen("debug.TXT","a");fputs(S,fp);fclose(fp);} */
24 /*#define DEBUG_LOG_INT(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);} */
25 /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);} */
26 
27 struct rectangle
28 {
29  double t, b, l, r;
30 };
31 
32 #ifdef HAVE_FT2BUILD_H
33 static int convert_str(const char *, const char *, unsigned char **);
34 static void release_convert_str(unsigned char *);
35 static void set_matrix(FT_Matrix *);
36 static void draw_text(FT_Face, FT_Vector *, FT_Matrix *,
37  const unsigned char *, int, int, struct rectangle *);
38 static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
39 static void set_text_box(FT_Bitmap *, FT_Int, FT_Int, struct rectangle *);
40 #endif
41 
42 static void draw_main(double x, double y, const char *string,
43  struct rectangle *box)
44 {
45 #ifdef HAVE_FT2BUILD_H
46  FT_Library library;
47  FT_Face face;
48  FT_Matrix matrix;
49 
50  /*FT_UInt glyph_index; */
51  FT_Vector pen;
52  FT_Error ans;
53  const char *filename;
54  const char *encoding;
55  int font_index;
56  unsigned char *out;
57  int outlen;
58 
59  /* get file name */
60  filename = font_get_freetype_name();
61  encoding = font_get_encoding();
62  font_index = font_get_index();
63 
64  /* set freetype */
65  ans = FT_Init_FreeType(&library);
66  if (ans) {
67  /* DEBUG_LOG("Text3 error: ft init\n"); */
68  return;
69  }
70  ans = FT_New_Face(library, filename, font_index, &face);
71  if (ans == FT_Err_Unknown_File_Format) {
72  /* DEBUG_LOG("Text3 error: ft new face 1\n"); */
73  FT_Done_FreeType(library);
74  return;
75  }
76  else if (ans) {
77  /* DEBUG_LOG("Text3 error: ft new face 2\n"); */
78  FT_Done_FreeType(library);
79  return;
80  }
81 
82  /* ans = FT_Set_Pixel_Sizes(face,10,10); */
83  /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,0,0); */
84  /* ans = FT_Set_Char_Size(face,10*64,0,72,0); */
85  /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,72,72); */
86  ans = FT_Set_Char_Size(face,
87  (int)(text_size_x * 64),
88  (int)(text_size_y * 64),
89  100, 100);
90 
91  if (ans) {
92  /* DEBUG_LOG("Text3 error: ft set size\n"); */
93  FT_Done_Face(face);
94  FT_Done_FreeType(library);
95  return;
96  }
97 
98  /* init point */
99  pen.x = x * 64;
100  /* pen.y = 0; */
101  pen.y = (screen_height - y) * 64;
102 
103  /* convert string to:shift-jis from:encoding */
104  outlen = convert_str(encoding, string, &out);
105 
106  /* set matrix */
107  set_matrix(&matrix);
108  /* draw */
109  draw_text(face, &pen, &matrix, out, outlen, 0, box);
110 
111  /* release */
112  release_convert_str(out);
113 
114  /* FT_done */
115  FT_Done_Face(face);
116  FT_Done_FreeType(library);
117 #endif
118 }
119 
120 #ifdef HAVE_FT2BUILD_H
121 static void set_matrix(FT_Matrix * matrix)
122 {
123  /* rotation is in radians */
124  matrix->xx = (FT_Fixed) ( text_cosrot * 0x10000);
125  matrix->xy = (FT_Fixed) (-text_sinrot * 0x10000);
126  matrix->yx = (FT_Fixed) ( text_sinrot * 0x10000);
127  matrix->yy = (FT_Fixed) ( text_cosrot * 0x10000);
128 }
129 
130 static int convert_str(const char *from, const char *in, unsigned char **out)
131 {
132  size_t len, i, res;
133  const unsigned char *p1;
134  unsigned char *p2;
135 
136  len = strlen(in);
137  res = 2 * (len + 1);
138 
139  *out = G_calloc(1, res);
140  p1 = (const unsigned char *)in;
141  p2 = *out;
142 
143 #ifdef HAVE_ICONV_H
144  {
145  iconv_t cd;
146 
147  i = res;
148  cd = iconv_open("UCS-2BE", from);
149  if (cd == (iconv_t) -1)
150  return -1;
151  if (iconv(cd, (char **)&p1, &len, (char **)&p2, &i) == (size_t) -1)
152  return -1;
153  iconv_close(cd);
154 
155  res -= i;
156  }
157 #else
158  for (i = 0; i <= len; i++)
159  /* Pad each character out to 2 bytes, i.e. UCS-2 Big Endian encoding
160  * (note low byte has already been zeroed by G_calloc() call) */
161  p2[2 * i + 1] = p1[i];
162 
163  res = 2 * len;
164 #endif
165 
166  return res;
167 }
168 
169 static void release_convert_str(unsigned char *out)
170 {
171  G_free(out);
172 }
173 
174 static void draw_text(FT_Face face, FT_Vector * pen, FT_Matrix * matrix,
175  const unsigned char *out, int len, int color,
176  struct rectangle *box)
177 {
178  FT_ULong ch;
179  FT_Error ans;
180  FT_GlyphSlot slot = face->glyph;
181  int i;
182 
183  for (i = 0; i < len; i += 2) {
184  ch = (out[i] << 8) | out[i + 1];
185  if (ch == 10)
186  continue;
187  /* transform */
188  FT_Set_Transform(face, matrix, pen);
189  /* get glyph image */
190  ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP);
191  if (ans)
192  continue;
193  ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
194  if (ans)
195  continue;
196  /* draw bitmap */
197  if (!box)
198  draw_bitmap(&slot->bitmap, slot->bitmap_left,
199  screen_height - slot->bitmap_top);
200  else
201  set_text_box(&slot->bitmap, slot->bitmap_left,
202  screen_height - slot->bitmap_top, box);
203 
204  /* increment pen position */
205  pen->x += slot->advance.x;
206  pen->y += slot->advance.y;
207  }
208 }
209 
210 static void set_text_box(FT_Bitmap *bitmap, FT_Int x, FT_Int y, struct rectangle *box)
211 {
212  FT_Int xMax = x + bitmap->width;
213  FT_Int yMax = y + bitmap->rows;
214 
215  if ((x == xMax) || (y == yMax))
216  return;
217  if (x < box->l)
218  box->l = x;
219  if (xMax > box->r)
220  box->r = xMax;
221  if (y < box->t)
222  box->t = y;
223  if (yMax > box->b)
224  box->b = yMax;
225 }
226 
227 static void draw_bitmap(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
228 {
229  static unsigned char *buf;
230  static int nalloc;
231  int w, h;
232  int bw = bitmap->width;
233  int bh = bitmap->rows;
234  const unsigned char *sbuf = bitmap->buffer;
235  int offset, i, j;
236  double x1, y1, x2, y2;
237 
238  x1 = x;
239  y1 = y;
240  x2 = x1 + bw;
241  y2 = y1 + bh;
242 
243  w = x2 - x1;
244  h = y2 - y1;
245  if (w <= 0 || h <= 0)
246  return;
247 
248  offset = ((int)y1 - y) * bw + (int)x1 - x;
249 
250  if (nalloc < w * h) {
251  nalloc = w * h;
252  buf = G_realloc(buf, nalloc);
253  }
254 
255  for (j = 0; j < h; j++)
256  for (i = 0; i < w; i++)
257  buf[j * w + i] = sbuf[offset + j * bw + i];
258 
259  COM_Pos_abs(x1, y1);
260  COM_Bitmap(w, h, 128, buf);
261 }
262 #endif
263 
264 void soft_text_freetype(const char *string)
265 {
266  draw_main(cur_x, cur_y, string, NULL);
267 }
268 
269 void get_text_ext_freetype(const char *string, double *top, double *bot, double *left, double *rite)
270 {
271  struct rectangle box;
272 
273  box.t = 1e300;
274  box.b = -1e300;
275  box.l = 1e300;
276  box.r = -1e300;
277 
278  draw_main(cur_x, cur_y, string, &box);
279 
280  *top = box.t;
281  *bot = box.b;
282  *left = box.l;
283  *rite = box.r;
284 }
285 
double text_size_y
Definition: driver/init.c:36
double b
Definition: text2.c:9
double cur_y
Definition: driver/init.c:33
const char * font_get_encoding(void)
Definition: font.c:34
double r
Definition: text2.c:9
void COM_Bitmap(int ncols, int nrows, int threshold, const unsigned char *buf)
Definition: driver/draw.c:4
double cur_x
Definition: driver/init.c:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
int screen_height
Definition: driver/init.c:30
double text_sinrot
Definition: driver/init.c:38
#define NULL
Definition: ccmath.h:32
#define x
#define G_calloc(m, n)
Definition: defs/gis.h:113
double top
Definition: clip.h:19
double text_size_x
Definition: driver/init.c:35
double rite
Definition: clip.h:19
const char * font_get_freetype_name(void)
Definition: font_freetype.c:20
void soft_text_freetype(const char *string)
Definition: text3.c:264
void get_text_ext_freetype(const char *string, double *top, double *bot, double *left, double *rite)
Definition: text3.c:269
Definition: clip.h:17
double bot
Definition: clip.h:19
double t
Definition: text2.c:9
#define G_realloc(p, n)
Definition: defs/gis.h:114
void COM_Pos_abs(double, double)
Definition: driver/move.c:4
int font_get_index(void)
Definition: font_freetype.c:25
double l
Definition: text2.c:9
double left
Definition: clip.h:19
double text_cosrot
Definition: driver/init.c:39