GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
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
30struct rectangle {
31 double t, b, l, r;
32};
33
34#ifdef HAVE_FT2BUILD_H
35static int convert_str(const char *, const char *, unsigned char **);
36static void release_convert_str(unsigned char *);
37static void set_matrix(FT_Matrix *);
38static void draw_text(FT_Face, FT_Vector *, FT_Matrix *, const unsigned char *,
39 int, struct rectangle *);
40static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
41static void set_text_box(FT_Bitmap *, FT_Int, FT_Int, struct rectangle *);
42#endif
43
44static 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
121static 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
130static 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
169static void release_convert_str(unsigned char *out)
170{
171 G_free(out);
172}
173
174static 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
209static 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
227static 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
264void soft_text_freetype(const char *string)
265{
266 draw_main(cur_x, cur_y, string, NULL);
267}
268
269void 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}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
#define NULL
Definition ccmath.h:32
void COM_Bitmap(int ncols, int nrows, int threshold, const unsigned char *buf)
Definition driver/draw.c:4
double b
double l
double t
double r
double text_size_y
Definition driver/init.c:36
int screen_height
Definition driver/init.c:30
void COM_Pos_abs(double, double)
Definition 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)
int font_get_index(void)
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