GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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 =
24  * fopen("debug.TXT","a");fputs(S,fp);fclose(fp);} */
25 /*#define DEBUG_LOG_INT(D) {FILE *fp =
26  * fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);} */
27 /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp =
28  * fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);} */
29 
30 struct rectangle {
31  double t, b, l, r;
32 };
33 
34 #ifdef HAVE_FT2BUILD_H
35 static int convert_str(const char *, const char *, unsigned char **);
36 static void release_convert_str(unsigned char *);
37 static void set_matrix(FT_Matrix *);
38 static void draw_text(FT_Face, FT_Vector *, FT_Matrix *, const unsigned char *,
39  int, struct rectangle *);
40 static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
41 static void set_text_box(FT_Bitmap *, FT_Int, FT_Int, struct rectangle *);
42 #endif
43 
44 static void draw_main(double x, double y, const char *string,
45  struct rectangle *box)
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 *encoding;
57  int font_index;
58  unsigned char *out;
59  int outlen;
60 
61  /* get file name */
62  filename = font_get_freetype_name();
63  encoding = font_get_encoding();
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 = FT_Set_Char_Size(face, (int)(text_size_x * 64),
89  (int)(text_size_y * 64), 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, 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, struct rectangle *box)
176 {
177  FT_ULong ch;
178  FT_Error ans;
179  FT_GlyphSlot slot = face->glyph;
180  int i;
181 
182  for (i = 0; i < len; i += 2) {
183  ch = (out[i] << 8) | out[i + 1];
184  if (ch == 10)
185  continue;
186  /* transform */
187  FT_Set_Transform(face, matrix, pen);
188  /* get glyph image */
189  ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP);
190  if (ans)
191  continue;
192  ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
193  if (ans)
194  continue;
195  /* draw bitmap */
196  if (!box)
197  draw_bitmap(&slot->bitmap, slot->bitmap_left,
198  screen_height - slot->bitmap_top);
199  else
200  set_text_box(&slot->bitmap, slot->bitmap_left,
201  screen_height - slot->bitmap_top, box);
202 
203  /* increment pen position */
204  pen->x += slot->advance.x;
205  pen->y += slot->advance.y;
206  }
207 }
208 
209 static void set_text_box(FT_Bitmap *bitmap, FT_Int x, FT_Int y,
210  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,
270  double *left, double *rite)
271 {
272  struct rectangle box;
273 
274  box.t = 1e300;
275  box.b = -1e300;
276  box.l = 1e300;
277  box.r = -1e300;
278 
279  draw_main(cur_x, cur_y, string, &box);
280 
281  *top = box.t;
282  *bot = box.b;
283  *left = box.l;
284  *rite = box.r;
285 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_realloc(p, n)
Definition: defs/gis.h:96
#define G_calloc(m, n)
Definition: defs/gis.h:95
void COM_Bitmap(int ncols, int nrows, int threshold, const unsigned char *buf)
Definition: driver/draw.c:4
double text_size_y
Definition: driver/init.c:36
int screen_height
Definition: driver/init.c:30
void COM_Pos_abs(double, double)
Definition: driver/move.c:4
double text_cosrot
Definition: driver/init.c:39
double text_size_x
Definition: driver/init.c:35
double cur_x
Definition: driver/init.c:32
double text_sinrot
Definition: driver/init.c:38
double cur_y
Definition: driver/init.c:33
const char * font_get_encoding(void)
Definition: font.c:34
const char * font_get_freetype_name(void)
Definition: font_freetype.c:20
int font_get_index(void)
Definition: font_freetype.c:25
double l
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
Definition: clip.h:14
double r
Definition: text2.c:8
double left
Definition: clip.h:15
double t
Definition: text2.c:8
double bot
Definition: clip.h:15
double b
Definition: text2.c:8
double l
Definition: text2.c:8
double rite
Definition: clip.h:15
double top
Definition: clip.h:15
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
#define x