@@ -12,7 +12,7 @@ const version_id = 'dev',
1212
1313/** @summary version date
1414 * @desc Release date in format day/month/year like '14/04/2022' */
15- version_date = '29 /09/2025',
15+ version_date = '30 /09/2025',
1616
1717/** @summary version id and date
1818 * @desc Produced by concatenation of {@link version_id} and {@link version_date}
@@ -98267,7 +98267,7 @@ let TH2Painter$2 = class TH2Painter extends THistPainter {
9826798267
9826898268}; // class TH2Painter
9826998269
98270- function createLatexGeometry(painter, lbl, size, as_array) {
98270+ function createLatexGeometry(painter, lbl, size, as_array, use_latex = true ) {
9827198271 const geom_args = { font: getHelveticaFont(), size, height: 0, curveSegments: 5 };
9827298272 if (THREE.REVISION > 162)
9827398273 geom_args.depth = 0;
@@ -98280,7 +98280,6 @@ function createLatexGeometry(painter, lbl, size, as_array) {
9828098280 }
9828198281
9828298282 const font_size = size * 100, geoms = [];
98283- let stroke_width = 5;
9828498283
9828598284 class TextParseWrapper {
9828698285
@@ -98290,6 +98289,7 @@ function createLatexGeometry(painter, lbl, size, as_array) {
9829098289 this.x = 0;
9829198290 this.y = 0;
9829298291 this.font_size = parent?.font_size ?? font_size;
98292+ this.stroke_width = parent?.stroke_width ?? 5;
9829398293 parent?.childs.push(this);
9829498294 }
9829598295
@@ -98300,22 +98300,20 @@ function createLatexGeometry(painter, lbl, size, as_array) {
9830098300 return new TextParseWrapper('text', this);
9830198301 if (kind === 'svg:path')
9830298302 return new TextParseWrapper('path', this);
98303- console.log('should create ', kind);
98303+ console.warn('missing handle for svg ', kind);
9830498304 }
9830598305
9830698306 style(name, value) {
98307- // console.log(`style ${name} = ${value}`);
9830898307 if ((name === 'stroke-width') && value)
98309- stroke_width = Number.parseInt(value);
98308+ this. stroke_width = Number.parseInt(value);
9831098309 return this;
9831198310 }
9831298311
9831398312 translate() {
98314- if (this.geom) {
98315- // special workaround for path elements, while 3d font is exact height, keep some space on the top
98316- // let dy = this.kind === 'path' ? this.font_size*0.002 : 0;
98317- this.geom.translate(this.x, this.y, 0);
98318- }
98313+ // special workaround for path elements, while 3d font is exact height, keep some space on the top
98314+ // let dy = this.kind === 'path' ? this.font_size*0.002 : 0;
98315+ this.geom?.translate(this.x, this.y, 0);
98316+
9831998317 this.childs.forEach(chld => {
9832098318 chld.x += this.x;
9832198319 chld.y += this.y;
@@ -98353,42 +98351,63 @@ function createLatexGeometry(painter, lbl, size, as_array) {
9835398351 this.y -= Number.parseInt(value)*0.01;
9835498352 else if ((name === 'fill') && (this.kind === 'text'))
9835598353 this.fill = value;
98356- else if ((name === 'd') && (this.kind === 'path')) {
98354+ else if ((name === 'd') && (this.kind === 'path') && (value !== 'M0,0') ) {
9835798355 if (get() !== 'M')
9835898356 return console.error('Not starts with M');
98359- const pnts = [];
9836098357 let x1 = getN(true), y1 = getN(), next;
98358+ const pnts = [], add_line = (x2, y2) => {
98359+ const angle = Math.atan2(y2 - y1, x2 - x1),
98360+ dx = 0.5 * this.stroke_width * Math.sin(angle),
98361+ dy = -0.5 * this.stroke_width * Math.cos(angle);
98362+ // front side
98363+ pnts.push(x1-dx, y1-dy, 0, x2-dx, y2-dy, 0, x2+dx, y2+dy, 0, x1-dx, y1-dy, 0, x2+dx, y2+dy, 0, x1+dx, y1+dy, 0);
98364+ // back side
98365+ pnts.push(x1-dx, y1-dy, 0, x2+dx, y2+dy, 0, x2-dx, y2-dy, 0, x1-dx, y1-dy, 0, x1+dx, y1+dy, 0, x2+dx, y2+dy, 0);
98366+ x1 = x2;
98367+ y1 = y2;
98368+ };
9836198369
9836298370 while ((next = get())) {
98363- let x2 = x1, y2 = y1;
9836498371 switch (next) {
98365- case 'L': x2 = getN(true); y2 = getN(); break;
98366- case 'l': x2 += getN(true); y2 += getN(); break;
98367- case 'H': x2 = getN(); break;
98368- case 'h': x2 += getN(); break;
98369- case 'V': y2 = getN(); break;
98370- case 'v': y2 += getN(); break;
98371- default: console.log('not supported operator', next);
98372+ case 'L': add_line(getN(true), getN()); continue;
98373+ case 'l': add_line(x1 + getN(true), y1 + getN()); continue;
98374+ case 'H': add_line(getN(), y1); continue;
98375+ case 'h': add_line(x1 + getN(), y1); continue;
98376+ case 'V': add_line(x1, getN()); continue;
98377+ case 'v': add_line(x1, y1 + getN()); continue;
98378+ case 'a': {
98379+ const rx = getN(true), ry = getN(true),
98380+ angle = getN(true)/180*Math.PI, flag1 = getN(true);
98381+ getN(true); // skip unused flag2
98382+ const x2 = x1 + getN(true),
98383+ y2 = y1 + getN(),
98384+ x0 = x1 + rx*Math.cos(angle),
98385+ y0 = y1 + ry*Math.sin(angle);
98386+ let angle2 = Math.atan2(y0 - y2, x0 - x2);
98387+ if (flag1 && (angle2 < angle))
98388+ angle2 += 2*Math.PI;
98389+ else if (!flag1 && (angle2 > angle))
98390+ angle2 -= 2*Math.PI;
98391+
98392+ for (let cnt = 0; cnt < 10; ++cnt) {
98393+ const a = angle + (angle2 - angle)/ 10 * (cnt + 1);
98394+ add_line(x0 - rx * Math.cos(a), y0 - ry * Math.sin(a));
98395+ }
98396+ continue;
98397+ }
98398+ default: console.log('not supported path operator', next);
9837298399 }
98373-
98374- const angle = Math.atan2(y2-y1, x2-x1),
98375- dx = 0.5 * stroke_width * Math.sin(angle),
98376- dy = -0.5 * stroke_width * Math.cos(angle);
98377-
98378- pnts.push(x1-dx, y1-dy, 0, x2-dx, y2-dy, 0, x2+dx, y2+dy, 0, x1-dx, y1-dy, 0, x2+dx, y2+dy, 0, x1+dx, y1+dy, 0);
98379-
98380- x1 = x2; y1 = y2;
9838198400 }
9838298401
98383- const pos = new Float32Array (pnts);
98384-
98385- this.geom = new THREE.BufferGeometry();
98386- this.geom._fill = this.fill;
98387- this.geom.setAttribute('position', new THREE.BufferAttribute(pos, 3));
98388- this.geom.scale(0.01, -0.01, 0.01);
98389- this.geom.computeVertexNormals();
98390-
98391- geoms.push(this.geom);
98402+ if (pnts.length) {
98403+ const pos = new Float32Array(pnts);
98404+ this.geom = new THREE.BufferGeometry();
98405+ this.geom._fill = this.fill;
98406+ this.geom.setAttribute('position', new THREE.BufferAttribute(pos, 3));
98407+ this.geom.scale(0.01, -0.01, 0.01);
98408+ this.geom.computeVertexNormals();
98409+ geoms.push(this.geom);
98410+ }
9839298411 }
9839398412 return this;
9839498413 }
@@ -98397,6 +98416,12 @@ function createLatexGeometry(painter, lbl, size, as_array) {
9839798416 if (this.kind === 'text') {
9839898417 geom_args.size = Math.round(0.01*this.font_size);
9839998418 this.geom = new THREE.TextGeometry(v, geom_args);
98419+ if (as_array) {
98420+ // this is latex parsing
98421+ // while three.js uses full height, make it more like normal fonts
98422+ this.geom.scale(1, 0.9, 1);
98423+ this.geom.translate(0, 0.0005*this.font_size, 0);
98424+ }
9840098425 this.geom._fill = this.fill;
9840198426 geoms.push(this.geom);
9840298427 }
@@ -98453,8 +98478,8 @@ function build3dlatex(obj) {
9845398478 const painter = new ObjectPainter(null, obj),
9845498479 handle = painter.createAttText({ attr: obj }),
9845598480 valign = handle.align % 10,
98456- halign = handle.align - valign,
98457- arr3d = createLatexGeometry(painter, obj.fTitle, handle.getSize() || 10, true),
98481+ halign = ( handle.align - valign) / 10 ,
98482+ arr3d = createLatexGeometry(painter, obj.fTitle, handle.getSize() || 10, true, obj._typename === clTLatex ),
9845898483 bb = new THREE.Box3().makeEmpty();
9845998484
9846098485 arr3d.forEach(geom => {
0 commit comments