1010 ******************************************************************************/
1111
1212#include " Boxes/construct.hpp"
13+ #include " Boxes/xkerning.hpp"
1314#include " analyze.hpp"
1415#include " boxes.hpp"
16+ #include " colors.hpp"
1517#include " cork.hpp"
1618#include " font.hpp"
1719#include " tm_debug.hpp"
1820
1921/* *****************************************************************************
2022 * Text boxes
2123 ******************************************************************************/
22-
23- struct xkerning_rep : concrete_struct {
24- SI padding;
25- SI left;
26- SI right;
27- xkerning_rep (SI p, SI l, SI r) : padding (p), left (l), right (r) {}
28- ~xkerning_rep () {}
29- };
30-
31- class xkerning {
32- CONCRETE_NULL (xkerning);
33- xkerning (SI p, SI l, SI r) : rep (tm_new<xkerning_rep> (p, l, r)) {};
34- };
35-
36- CONCRETE_NULL_CODE (xkerning);
37-
38- static bool
39- is_nil_or_zero (xkerning xk) {
40- return is_nil (xk) || (xk->left == 0 && xk->right == 0 && xk->padding == 0 );
41- }
42-
43- /* *****************************************************************************
44- * Text boxes
45- ******************************************************************************/
46-
4724struct text_box_rep : public box_rep {
4825 int pos;
4926 string str;
5027 font fn;
5128 pencil pen;
5229 xkerning xk;
30+ color bg_color;
5331
54- text_box_rep (path ip, int pos, string s, font fn, pencil pen, xkerning xk);
32+ text_box_rep (path ip, int pos, string s, font fn, pencil pen, xkerning xk,
33+ color bg= black);
5534 operator tree () { return str; }
5635 box adjust_kerning (int mode, double factor);
5736 box expand_glyphs (int mode, double factor);
@@ -99,8 +78,9 @@ struct text_box_rep : public box_rep {
9978 ******************************************************************************/
10079
10180text_box_rep::text_box_rep (path ip, int pos2, string s, font fn2, pencil p2,
102- xkerning xk2)
103- : box_rep (ip), pos (pos2), str (s), fn (fn2), pen (p2), xk (xk2) {
81+ xkerning xk2, color bg)
82+ : box_rep (ip), pos (pos2), str (s), fn (fn2), pen (p2), xk (xk2),
83+ bg_color (bg) {
10484 metric ex;
10585 fn->get_extents (str, ex);
10686 x1= ex->x1 ;
@@ -111,6 +91,7 @@ text_box_rep::text_box_rep (path ip, int pos2, string s, font fn2, pencil p2,
11191 y3= ex->y3 ;
11292 x4= ex->x4 ;
11393 y4= ex->y4 ;
94+
11495 if (!is_nil (xk)) {
11596 STACK_NEW_ARRAY (xpos, SI, N (str) + 1 );
11697 fn->get_xpositions (str, xpos, xk->padding );
@@ -139,7 +120,9 @@ text_box_rep::adjust_kerning (int mode, double factor) {
139120 }
140121 if ((mode & START_OF_LINE) != 0 ) nxk->left -= pad;
141122 if ((mode & END_OF_LINE) != 0 ) nxk->right -= pad;
142- return tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk);
123+ text_box_rep* rep=
124+ tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk, bg_color);
125+ return (box) rep;
143126}
144127
145128box
@@ -152,8 +135,9 @@ text_box_rep::right_contract_kerning (double factor) {
152135 nxk->padding = xk->padding ;
153136 }
154137 nxk->right -= pad;
155- box result= tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk);
156- return result;
138+ text_box_rep* rep=
139+ tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk, bg_color);
140+ return (box) rep;
157141}
158142
159143box
@@ -166,7 +150,9 @@ text_box_rep::left_contract_kerning (double factor) {
166150 nxk->padding = xk->padding ;
167151 }
168152 nxk->left -= pad;
169- return tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk);
153+ text_box_rep* rep=
154+ tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk, bg_color);
155+ return (box) rep;
170156}
171157
172158box
@@ -178,7 +164,9 @@ text_box_rep::right_auto_spacing (SI size) {
178164 nxk->padding = xk->padding ;
179165 }
180166 nxk->right = nxk->right + size;
181- return tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk);
167+ text_box_rep* rep=
168+ tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk, bg_color);
169+ return (box) rep;
182170}
183171
184172box
@@ -190,18 +178,44 @@ text_box_rep::left_auto_spacing (SI size) {
190178 nxk->padding = xk->padding ;
191179 }
192180 nxk->left = nxk->left + size;
193- return tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk);
181+ text_box_rep* rep=
182+ tm_new<text_box_rep> (ip, pos, str, fn, pen, nxk, bg_color);
183+ return (box) rep;
194184}
195185
196186box
197187text_box_rep::expand_glyphs (int mode, double factor) {
198188 if (N (str) == 0 ) return this ;
199- font nfn= fn->magnify (1.0 + factor, 1.0 );
200- return tm_new<text_box_rep> (ip, pos, str, nfn, pen, xk);
189+ font nfn= fn->magnify (1.0 + factor, 1.0 );
190+ text_box_rep* rep=
191+ tm_new<text_box_rep> (ip, pos, str, nfn, pen, xk, bg_color);
192+ return (box) rep;
201193}
202194
203195void
204196text_box_rep::display (renderer ren) {
197+ // 如果有背景色(非透明),先绘制背景
198+ int r, g, b, a;
199+ get_rgb_color (bg_color, r, g, b, a);
200+ if (a > 0 ) {
201+ brush bg_brush (bg_color);
202+ ren->set_background (bg_brush);
203+ SI bg_x1= x1;
204+ SI bg_x2= x2;
205+ metric ex_m;
206+ fn->get_extents (" M" , ex_m);
207+ SI bg_y1= ex_m->y1 - 10 * ren->pixel ; // 向下延伸10个像素
208+ SI bg_y2= ex_m->y2 + 10 * ren->pixel ; // 向上延伸10个像素
209+
210+ // 检查背景宽度是否足够
211+ SI bg_width= bg_x2 - bg_x1;
212+ SI m_width = ex_m->x2 - ex_m->x1 ;
213+ if (bg_width >= m_width / 4 ) {
214+ ren->clear (bg_x1, bg_y1, bg_x2, bg_y2);
215+ }
216+ }
217+
218+ // 绘制文本(如果有文本)
205219 if (N (str) > 0 ) {
206220 ren->set_pencil (pen);
207221 if (is_nil_or_zero (xk)) fn->draw (ren, str, 0 , 0 );
@@ -690,5 +704,12 @@ wide_stix_box (path ip, string s, font fn, pencil pen, SI width) {
690704
691705box
692706text_box (path ip, int pos, string s, font fn, pencil pen) {
693- return tm_new<text_box_rep> (ip, pos, s, fn, pen, xkerning ());
707+ return tm_new<text_box_rep> (ip, pos, s, fn, pen, xkerning (),
708+ rgb_color (0 , 0 , 0 , 0 ));
709+ }
710+
711+ box
712+ text_box_with_bg (path ip, int pos, string s, font fn, pencil pen, color bg,
713+ xkerning xk) {
714+ return tm_new<text_box_rep> (ip, pos, s, fn, pen, xk, bg);
694715}
0 commit comments