Skip to content

Commit b622daf

Browse files
da-liiiclaude
andauthored
[204_24] 支持 bg-color 属性用于调整文本盒子的背景色 (#2339)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent fd733af commit b622daf

File tree

8 files changed

+262
-43
lines changed

8 files changed

+262
-43
lines changed

TeXmacs/packages/standard/std-markup.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,7 @@
476476

477477
<assign|marked-color|#ffe47f>
478478

479-
<assign|marked-padding|0.2fn>
480-
481-
<assign|marked|<macro|body|<quasi|<style-with|src-compact|none|<datoms|<macro|x|<style-with|src-compact|none|<tabular|<tformat|<cwith|1|1|1|1|cell-background|<unquote|<value|marked-color>>>|<cwith|1|1|1|1|cell-lsep|<unquote|<value|marked-padding>>>|<cwith|1|1|1|1|cell-rsep|<unquote|<value|marked-padding>>>|<cwith|1|1|1|1|cell-bsep|<unquote|<value|marked-padding>>>|<cwith|1|1|1|1|cell-tsep|<unquote|<value|marked-padding>>>|<cwith|1|-1|1|-1|cell-lborder|0ln>|<cwith|1|-1|1|-1|cell-rborder|0ln>|<cwith|1|-1|1|-1|cell-bborder|0ln>|<cwith|1|-1|1|-1|cell-tborder|0ln>|<twith|table-width|>|<twith|table-valign|B>|<twith|table-hmode|auto>|<twith|table-block|no>|<table|<row|<cell|<arg|x>>>>>>>>|<arg|body>>>>>>
479+
<assign|marked|<macro|body|<with|bg-color|<value|marked-color>|<arg|body>>>>
482480

483481
<drd-props|marked|with-like|yes|arity|1|accessible|all>
484482

TeXmacs/tests/tmu/204_24.tmu

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<TMU|<tuple|1.1.0|2025.2.3-beta4>>
2+
3+
<style|<tuple|generic|number-europe|chinese>>
4+
5+
<\body>
6+
Test 204_24: Text background color (Chinese)
7+
8+
<section|文本>
9+
10+
普通文本,无背景色
11+
12+
\;
13+
14+
<with|bg-color|yellow|黄色背景的文本>
15+
16+
\;
17+
18+
<with|bg-color|light gray|浅灰色背景的文本>
19+
20+
\;
21+
22+
<with|bg-color|#e0e0ff|#e0e0ff 颜色背景的文本>
23+
24+
\;
25+
26+
<with|bg-color|#ffcccc|<with|color|red|红色文字配粉色背景>>
27+
28+
\;
29+
30+
<with|bg-color|#ccffcc|<with|color|dark green|深绿色文字配浅绿色背景>>
31+
32+
<\with|bg-color|#ffffcc>
33+
多行文本块带有浅黄色背景。 这是对多行背景色支持的测试。 背景应该覆盖整个文本块。我们需要提供更多文字,才能覆盖多行。
34+
</with>
35+
36+
<\with|bg-color|#ffffcc>
37+
多行文本块带有浅黄色背景。 这是对多行背景色支持的测试。\
38+
39+
背景应该覆盖整个文本块。
40+
</with>
41+
42+
单个空格:<marked| >
43+
44+
两个空格:<marked| \ >
45+
46+
空格在字符左边:<marked| abc>
47+
48+
空格在字符右边:<marked|abc >\
49+
50+
<section|数学模式>
51+
52+
\;
53+
54+
数学公式背景测试:
55+
56+
<\with|bg-color|light blue>
57+
<\equation*>
58+
E=mc<rsup|2>
59+
</equation*>
60+
</with>
61+
62+
\;
63+
64+
<with|bg-color|#ffeeee|行内数学 <with|mode|math|<frac|a|b>> 带背景>
65+
</body>
66+
67+
<\initial>
68+
<\collection>
69+
<associate|page-medium|paper>
70+
<associate|page-screen-margin|false>
71+
</collection>
72+
</initial>
73+
74+
<\references>
75+
<\collection>
76+
<associate|auto-1|<tuple|1|1>>
77+
<associate|auto-2|<tuple|2|1>>
78+
</collection>
79+
</references>
80+
81+
<\auxiliary>
82+
<\collection>
83+
<\associate|toc>
84+
<vspace*|1fn><with|font-series|<quote|bold>|math-font-series|<quote|bold>|1<space|2spc>文本><datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.05fn>.<space|0.05fn>>>>>|<htab|5mm>><no-break><pageref|auto-1><vspace|0.5fn>
85+
86+
<vspace*|1fn><with|font-series|<quote|bold>|math-font-series|<quote|bold>|2<space|2spc>数学模式><datoms|<macro|x|<repeat|<arg|x>|<with|font-series|medium|<with|font-size|1|<space|0.05fn>.<space|0.05fn>>>>>|<htab|5mm>><no-break><pageref|auto-2><vspace|0.5fn>
87+
</associate>
88+
</collection>
89+
</auxiliary>

devel/204_24.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# 204_24
2+
## 如何测试
3+
1. 打开`TeXmacs/tests/tmu/204_24.tmu`,直接观察文档的颜色是否合理
4+
2. 调整文档的语言,比如换成英语,观察文档颜色是否合理
5+
6+
## 2025/12/25 支持bg-color属性
7+
### What
8+
1. marked改为使用bg-color实现
9+
2. 在排版引擎中添加bg-color的支持

src/Typeset/Boxes/Basic/text_boxes.cpp

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,27 @@
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-
4724
struct 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

10180
text_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

145128
box
@@ -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

159143
box
@@ -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

172158
box
@@ -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

184172
box
@@ -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

196186
box
197187
text_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

203195
void
204196
text_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

691705
box
692706
text_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
}

src/Typeset/Boxes/construct.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#ifndef CONSTRUCT_H
1313
#define CONSTRUCT_H
14+
#include "Boxes/xkerning.hpp"
1415
#include "array.hpp"
1516
#include "boxes.hpp"
1617
#include "command.hpp"
@@ -106,6 +107,8 @@ box polygon_box (path ip, array<SI> x, array<SI> y, brush fill, pencil pen);
106107
box image_box (path ip, url u, SI w, SI h, int alpha, int px);
107108

108109
box text_box (path ip, int pos, string s, font fn, pencil pen);
110+
box text_box_with_bg (path ip, int pos, string s, font fn, pencil pen, color bg,
111+
xkerning xk);
109112
box delimiter_box (path ip, string s, font fn, pencil pen, SI y1, SI y2);
110113
box delimiter_box (path ip, string s, font fn, pencil pen, SI bot, SI top,
111114
SI mid, SI real_bot, SI real_top);

src/Typeset/Boxes/xkerning.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/******************************************************************************
2+
* MODULE : xkerning.hpp
3+
* DESCRIPTION: Extended kerning for text boxes
4+
* COPYRIGHT : (C) 1999 Joris van der Hoeven
5+
* 2025 Mogan STEM authors
6+
*******************************************************************************
7+
* This software falls under the GNU general public license version 3 or later.
8+
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9+
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10+
******************************************************************************/
11+
12+
#ifndef XKERNING_H
13+
#define XKERNING_H
14+
15+
#include "basic.hpp"
16+
17+
struct xkerning_rep : concrete_struct {
18+
SI padding;
19+
SI left;
20+
SI right;
21+
xkerning_rep (SI p, SI l, SI r) : padding (p), left (l), right (r) {}
22+
~xkerning_rep () {}
23+
};
24+
25+
class xkerning {
26+
CONCRETE_NULL (xkerning);
27+
xkerning (SI p, SI l, SI r) : rep (tm_new<xkerning_rep> (p, l, r)) {};
28+
};
29+
30+
CONCRETE_NULL_CODE (xkerning);
31+
32+
static inline bool
33+
is_nil_or_zero (xkerning xk) {
34+
return is_nil (xk) || (xk->left == 0 && xk->right == 0 && xk->padding == 0);
35+
}
36+
37+
#endif // XKERNING_H

0 commit comments

Comments
 (0)