1
1
/*
2
2
* lib/pandagl/src/text/text.c
3
3
*
4
- * Copyright (c) 2023, Liu Chao <i@lc-soft.io> All rights reserved.
4
+ * Copyright (c) 2018- 2023, Liu Chao <i@lc-soft.io> All rights reserved.
5
5
*
6
6
* SPDX-License-Identifier: MIT
7
7
*
8
8
* This file is part of LCUI, distributed under the MIT License found in the
9
9
* LICENSE.TXT file in the root directory of this source tree.
10
10
*/
11
11
12
- /*
13
- * textlayer.c -- text layout and rendering module.
14
- *
15
- * copyright (c) 2018, liu chao <lc-soft@live.cn> all rights reserved.
16
- *
17
- * redistribution and use in source and binary forms, with or without
18
- * modification, are permitted provided that the following conditions are met:
19
- *
20
- * * redistributions of source code must retain the above copyright notice,
21
- * this list of conditions and the following disclaimer.
22
- * * redistributions in binary form must reproduce the above copyright
23
- * notice, this list of conditions and the following disclaimer in the
24
- * documentation and/or other materials provided with the distribution.
25
- * * neither the name of lcui nor the names of its contributors may be used
26
- * to endorse or promote products derived from this software without
27
- * specific prior written permission.
28
- *
29
- * this software is provided by the copyright holders and contributors "as is"
30
- * and any express or implied warranties, including, but not limited to, the
31
- * implied warranties of merchantability and fitness for a particular purpose
32
- * are disclaimed. in no event shall the copyright owner or contributors be
33
- * liable for any direct, indirect, incidental, special, exemplary, or
34
- * consequential damages (including, but not limited to, procurement of
35
- * substitute goods or services; loss of use, data, or profits; or business
36
- * interruption) however caused and on any theory of liability, whether in
37
- * contract, strict liability, or tort (including negligence or otherwise)
38
- * arising in any way out of the use of this software, even if advised of the
39
- * possibility of such damage.
40
- */
41
-
42
12
#include <stdlib.h>
43
13
#include <wctype.h>
44
14
#include <pandagl.h>
15
+ #include <math.h>
45
16
46
17
typedef enum { PD_TEXT_ACTION_INSERT , PD_TEXT_ACTION_APPEND } pd_text_action_t ;
47
18
48
- #define get_default_line_height ( h ) y_iround(h * 1.42857143)
19
+ #define DEFAULT_LINE_HEIGHT 1.42857143
49
20
#define isalpha (ch ) (ch >= 'a' && ch <= 'z') || (ch >= 'a' && ch <= 'z')
50
21
51
22
static void pd_text_line_init (pd_text_line_t * line )
@@ -55,7 +26,6 @@ static void pd_text_line_init(pd_text_line_t *line)
55
26
line -> length = 0 ;
56
27
line -> string = NULL ;
57
28
line -> eol = PD_TEXT_EOL_NONE ;
58
- line -> text_height = 0 ;
59
29
}
60
30
61
31
static void pd_text_line_destroy (pd_text_line_t * line )
@@ -69,7 +39,6 @@ static void pd_text_line_destroy(pd_text_line_t *line)
69
39
line -> width = 0 ;
70
40
line -> height = 0 ;
71
41
line -> length = 0 ;
72
- line -> text_height = 0 ;
73
42
if (line -> string ) {
74
43
free (line -> string );
75
44
}
@@ -134,24 +103,24 @@ PD_INLINE pd_text_line_t *pd_text_get_line(pd_text_t *text, int line_num)
134
103
static void pd_text_update_line_size (pd_text_t * text , pd_text_line_t * line )
135
104
{
136
105
int i ;
137
- pd_char_t * txtchar ;
106
+ int text_height = text -> default_style .pixel_size ;
107
+ pd_char_t * ch ;
138
108
139
109
line -> width = 0 ;
140
- line -> text_height = text -> default_style .pixel_size ;
141
110
for (i = 0 ; i < line -> length ; ++ i ) {
142
- txtchar = line -> string [i ];
143
- if (!txtchar -> bitmap ) {
111
+ ch = line -> string [i ];
112
+ if (!ch -> bitmap ) {
144
113
continue ;
145
114
}
146
- line -> width += txtchar -> bitmap -> advance . x ;
147
- if (line -> text_height < txtchar -> bitmap -> advance . y ) {
148
- line -> text_height = txtchar -> bitmap -> advance . y ;
115
+ line -> width += ch -> bitmap -> metrics . hori_advance ;
116
+ if (text_height < ch -> bitmap -> metrics . vert_advance ) {
117
+ text_height = ch -> bitmap -> metrics . vert_advance ;
149
118
}
150
119
}
151
120
if (text -> line_height > 0 ) {
152
121
line -> height = text -> line_height ;
153
122
} else {
154
- line -> height = get_default_line_height ( line -> text_height );
123
+ line -> height = ( int ) round ( text_height * DEFAULT_LINE_HEIGHT );
155
124
}
156
125
}
157
126
@@ -386,14 +355,16 @@ static int pd_text_get_line_rect(pd_text_t *text, int line_num, int start_col,
386
355
if (!line -> string [i ]-> bitmap ) {
387
356
continue ;
388
357
}
389
- rect -> x += line -> string [i ]-> bitmap -> advance .x ;
358
+ rect -> x +=
359
+ line -> string [i ]-> bitmap -> metrics .hori_advance ;
390
360
}
391
361
rect -> width = 0 ;
392
362
for (i = start_col ; i <= end_col && i < line -> length ; ++ i ) {
393
363
if (!line -> string [i ]-> bitmap ) {
394
364
continue ;
395
365
}
396
- rect -> width += line -> string [i ]-> bitmap -> advance .x ;
366
+ rect -> width +=
367
+ line -> string [i ]-> bitmap -> metrics .hori_advance ;
397
368
}
398
369
}
399
370
if (rect -> width <= 0 || rect -> height <= 0 ) {
@@ -494,9 +465,10 @@ int pd_text_set_insert_pixel_position(pd_text_t *text, int x, int y)
494
465
if (!txtchar -> bitmap ) {
495
466
continue ;
496
467
}
497
- pixel_pos += txtchar -> bitmap -> advance . x ;
468
+ pixel_pos += txtchar -> bitmap -> metrics . hori_advance ;
498
469
/* 如果在当前字中心点的前面 */
499
- if (x <= pixel_pos - txtchar -> bitmap -> advance .x / 2 ) {
470
+ if (x <=
471
+ pixel_pos - txtchar -> bitmap -> metrics .hori_advance / 2 ) {
500
472
ins_x = i ;
501
473
break ;
502
474
}
@@ -531,7 +503,7 @@ int pd_text_get_char_pixel_position(pd_text_t *text, int line_num, int col,
531
503
if (!txtchar || !txtchar -> bitmap ) {
532
504
continue ;
533
505
}
534
- pixel_x += txtchar -> bitmap -> advance . x ;
506
+ pixel_x += txtchar -> bitmap -> metrics . hori_advance ;
535
507
}
536
508
pixel_pos -> x = pixel_x ;
537
509
pixel_pos -> y = pixel_y ;
@@ -607,7 +579,7 @@ static void pd_text_typeset_line(pd_text_t *text, int line_num)
607
579
continue ;
608
580
}
609
581
/* 累加行宽度 */
610
- line_width += txtchar -> bitmap -> advance . x ;
582
+ line_width += txtchar -> bitmap -> metrics . hori_advance ;
611
583
/* 如果是当前行的第一个字符,或者行宽度没有超过宽度限制 */
612
584
if (!autowrap || col < 1 || line_width <= max_width ) {
613
585
if (isalpha (txtchar -> code )) {
@@ -851,7 +823,7 @@ int pd_text_get_width(pd_text_t *text)
851
823
!line -> string [i ]-> bitmap -> buffer ) {
852
824
continue ;
853
825
}
854
- w += line -> string [i ]-> bitmap -> advance . x ;
826
+ w += line -> string [i ]-> bitmap -> metrics . hori_advance ;
855
827
}
856
828
if (w > max_w ) {
857
829
max_w = w ;
@@ -1196,58 +1168,34 @@ static void pd_text_render_line(pd_text_t *text, pd_rect_t *area,
1196
1168
pd_canvas_t * graph , pd_pos_t layer_pos ,
1197
1169
pd_text_line_t * line , int y )
1198
1170
{
1199
- pd_char_t * txtchar ;
1200
- pd_pos_t ch_pos ;
1201
- int baseline , col , x ;
1171
+ pd_char_t * ch ;
1172
+ pd_pos_t pen ;
1173
+ int col , x ;
1202
1174
1203
- baseline = line -> text_height * 4 / 5 ;
1204
1175
x = pd_text_get_line_start_x (text , line ) + text -> offset_x ;
1205
- /* 确定从哪个文字开始绘制 */
1206
- for (col = 0 ; col < line -> length ; ++ col ) {
1207
- txtchar = line -> string [col ];
1208
- /* 忽略无字体位图的文字 */
1209
- if (!txtchar -> bitmap ) {
1176
+ for (col = 0 ; col < line -> length && x < area -> x + area -> width ; ++ col ) {
1177
+ ch = line -> string [col ];
1178
+ if (!ch -> bitmap ) {
1210
1179
continue ;
1211
1180
}
1212
- x += txtchar -> bitmap -> advance .x ;
1213
- if (x > area -> x ) {
1214
- x -= txtchar -> bitmap -> advance .x ;
1215
- break ;
1216
- }
1217
- }
1218
- /* 若一整行的文本都不在可绘制区域内 */
1219
- if (col >= line -> length ) {
1220
- y += line -> height ;
1221
- return ;
1222
- }
1223
- /* 遍历该行的文字 */
1224
- for (; col < line -> length ; ++ col ) {
1225
- txtchar = line -> string [col ];
1226
- if (!txtchar -> bitmap ) {
1181
+ if (x + ch -> bitmap -> metrics .hori_advance < area -> x ) {
1227
1182
continue ;
1228
1183
}
1229
- /* 计算字体位图的绘制坐标 */
1230
- ch_pos .x = layer_pos .x + x ;
1231
- ch_pos .y = layer_pos .y + y ;
1232
- if (txtchar -> style && txtchar -> style -> has_back_color ) {
1184
+ pen .x = layer_pos .x + x ;
1185
+ pen .y = layer_pos .y + y ;
1186
+ if (ch -> style && ch -> style -> has_back_color ) {
1233
1187
pd_rect_t rect ;
1234
- rect .x = ch_pos .x ;
1235
- rect .y = ch_pos .y ;
1188
+ rect .x = pen .x ;
1189
+ rect .y = pen .y ;
1236
1190
rect .height = line -> height ;
1237
- rect .width = txtchar -> bitmap -> advance .x ;
1238
- pd_canvas_fill_rect (graph , txtchar -> style -> back_color ,
1239
- rect );
1240
- }
1241
- ch_pos .x += txtchar -> bitmap -> left ;
1242
- ch_pos .y += baseline ;
1243
- ch_pos .y += (line -> height - baseline ) / 2 ;
1244
- ch_pos .y -= txtchar -> bitmap -> top ;
1245
- pd_text_render_char (text , txtchar , graph , ch_pos );
1246
- x += txtchar -> bitmap -> advance .x ;
1247
- /* 如果超过绘制区域则不继续绘制该行文本 */
1248
- if (x > area -> x + area -> width ) {
1249
- break ;
1191
+ rect .width = ch -> bitmap -> metrics .hori_advance ;
1192
+ pd_canvas_fill_rect (graph , ch -> style -> back_color , rect );
1250
1193
}
1194
+ pen .x += ch -> bitmap -> left ;
1195
+ pen .y += (line -> height - ch -> bitmap -> metrics .bbox_height ) /
1196
+ 2 + ch -> bitmap -> metrics .ascender - ch -> bitmap -> top ;
1197
+ pd_text_render_char (text , ch , graph , pen );
1198
+ x += ch -> bitmap -> metrics .hori_advance ;
1251
1199
}
1252
1200
}
1253
1201
0 commit comments