数式中のボックスとベースライン補正

数式中のボックスとベースライン補正

- 北川 弘典 の投稿
返信数: 23
ベースライン補正が 0  でないときの tabular 環境の垂直位置について
考えていたのですが,その過程で
 文中数式モードでは自動的に全体にベースライン補正がかかり,
 その結果 $\hbox{漢字ABC}$ では「漢字」に一重,
 「ABC」に二重にベースライン補正が適用される
という pTeX の仕様について疑問を持ったので,実験してみました.
(参考:qa: 54286)

手元で「数式中の explicit なボックスは,
自動で入るベースライン補正を打ち消すように垂直位置をずらす」
というパッチを作り,次のソースで試してみました.
添付ファイルの黒が現行の pTeX の挙動,薄青がパッチ後の挙動です.

%%%%%%%%
\ifdefined\enablecjktoken
  \documentclass[uplatex]{jsarticle}
\else
  \documentclass{jsarticle}
\fi
\usepackage{amsmath}
\textwidth300pt
\begin{document}
\ybaselineshift=10pt
\noautoxspacing
\def\R{\vrule height 0.4pt depth 0pt width 10pt}
あいうえおABC$%
  \hbox{漢X\R}\vbox{\hsize=3em 字Y\hss}\R xyz\frac{\text{漢X\R}\R213}{s}
  \displaystyle\int_{0}^{\text{漢X\R}\R1}
$\vrule height 50pt depth 40pt

qa:54286
\begin{equation}
  y = f(x)= x^2+2x+1 + \int_{0}^{\pi} \frac{1+tx^2}{1-t^2}\,dt
\end{equation}
\end{document}
%%%%%%%%

「地の数式」中に配置したボックスについては良さそうに
思えますが,逆に,分数や添字中に \hbox を配置した場合は
欧文のベースラインが揃わなくなっています.
(折衷案としては,「\textstyle, \displaystyle のみ打ち消す」?)

何か感想や意見などがありましたらお願い致します.
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- 北川 弘典 の投稿
> 逆に,分数や添字中に \hbox を配置した場合は
> 欧文のベースラインが揃わなくなっています.
ここ,なんだかおかしな表現になっていますね,すみません.

> 折衷案としては,「\textstyle, \displaystyle のみ打ち消す」?
作ってみました.同じものを ptex-base.ch へのパッチも含めて
https://github.com/h-kitagawa/plext_test/tree/master/ptex_bls_math
に置いています.

横組では \ybaselineshift = 0 pt の場合が多いと思うので
そんなに影響はないでしょうけど,やっぱり副作用が気になります…….
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
北川さんのパッチをあててビルドしてみました。新しいもののほうが
私は自然だと思います。ただ、

\documentclass{jarticle}
\begin{document}
\ybaselineshift10pt
あいうabc\underline{あいうabc}あいうabc
\end{document}

みたいなケース(下線部が二重にシフトする)はまだ解消しないようです。
aminophen への返信

Re: 数式中のボックスとベースライン補正

- 北川 弘典 の投稿
> 下線部が二重にシフトする
確かにそうですね.
 ABCあ$\underline{\hbox{漢X}213}$%
 ABCあ$\underline{\hbox{漢X}}$
だけでも違いが確認できますね,やっぱりまだ甘かったです.

結構 TeX の内部まで改造しないといけないような気がしています.
(具体的に言うと,sub_box という math_type を
 sub_box(TeX の数式組版処理の途中で生成)と
 sub_exp_box(明示的な hbox, vbox)に分割する???)
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- 北見 けん の投稿
おかげさまで TeX を便利に使わせていただいています。
ユーザーの一人として感謝しています。

さて、そもそもの pTeX の baselineshift の仕組みは、
和文フォントと欧文フォントのデザイン上のミスマッチを補正するのが目的だったと思います。
そうすると、シフトする対象を和文中の欧文と和文中の数式ボックスとするのではなく、
シフトの対象は欧文フォントや数式シンボルフォント自体とするのが合理的ではないかと思います。
フォント自体をシフトするにはバーチャルフォントを使っても実現できると思いますが、
それだとシフト量をマクロレベルで簡単に変えられないので、
次のような仕組みが考えられないでしょうか。
それは、フォントごとのシフト量を pTeX に保持させて、
新しいプリミティブで個別のフォントのシフト量を変更できるようにする仕組みです。

私には pTeX を改変する技術はないので、いうだけになってしまって申し訳ないのですが、
中に和文を含むかもしれないような数式ボックスをボックスごとシフトしてしまうことで
問題が複雑化しているのが、この方針で一気に解消できるように思いました。

pTeXの実装はよくわからないのですが、
内部でフォントの高さや深さを利用するところすべてを変更する必要があるのかもしれないので、
そうするとかなりの大改造になりそうなのが心配です。

と、書いた後で思ったのですが、数式の axis のシフト量はどうすべきか悩ましいですね。

北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- 北川 弘典 の投稿
> 確かにそうですね.
>  ABCあ$\underline{\hbox{漢X}213}$%
>  ABCあ$\underline{\hbox{漢X}}$
> だけでも違いが確認できますね,やっぱりまだ甘かったです.
\underline などにも効くようにしてみました.
(添付ファイル中,黒が現行の pTeX の挙動,薄青がパッチ後の挙動)

\displaystyle, \textstyle での明示的なボックスの「シフト打ち消し」量を
指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
\scriptbaselineshiftfactor(標準値は 700: 0.7倍),
\scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
利用者が設定できるようにしています.
いずれも 0 にすると,現行の pTeX の挙動と一致するはずです.

なお,$あ$ のように数式モードの中で直に書かれた和文文字に対しては
何もしていません.
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
> \displaystyle, \textstyle での明示的なボックスの「シフト打ち消し」量を
> 指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
> \scriptbaselineshiftfactor(標準値は 700: 0.7倍),
> \scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
> 利用者が設定できるようにしています.
> いずれも 0 にすると,現行の pTeX の挙動と一致するはずです.
ビルドしてみました。いまのところ変な結果は出ていません。
[D or T] : [S] : [SS] = 1000 : 700 : 500
の規定値はフォントサイズ由来という理解でよければ
和文フォントと欧文フォントのデザイン上のミスマッチを補正する」
という観点からも素晴らしいと思います。
aminophen への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
少しそれますが、気になったので。
\ybaselineshift の値を0ptから徐々に大きくしていくと、
LaTeX のロゴの「A」が徐々に上がらなくなっていくの
ですが、これはそういう仕様でしょうか?
(これはパッチをあてる前と後で同じです)

\documentclass{jarticle}
\begin{document}
\ybaselineshift2pt
\LaTeX のロゴ。
\ybaselineshift7pt
\LaTeX のロゴ。
\end{document}
aminophen への返信

Re: 数式中のボックスとベースライン補正

- でび まる の投稿
でびまるといいます。とんでもなくバカなことしてるんだと
思いますが、

> \ybaselineshift の値を0ptから徐々に大きくしていくと、
> LaTeX のロゴの「A」が徐々に上がらなくなっていくの

これが確認できません。ロゴ全体は下っていきますが「A」
の位置は同じように見えます。どうでしょうか。
でび まる への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
> LaTeX のロゴの「A」が徐々に上がらなくなっていく
PDF を作ったので添付します。ソースは「2016年 03月 01日(火曜日) 18:39」
に例示したものです。作成環境は
TeX Live 2015 + LaTeX 2016/02/01 + pLaTeX 2006/11/10
です。TeXを使ってみよう(upTeX版)
http://glc.l.u-tokyo.ac.jp/texonweb/
も使ってみましたが(jarticle → ujarticle)、まったく同じです。

This is e-pTeX, Version 3.14159265-p3.6-141210-2.6 (utf8.euc) (TeX Live 2015)
pLaTeX2e <2006/11/10> (based on LaTeX2e <2016/02/01> patch level 0)
aminophen への返信

Re: 数式中のボックスとベースライン補正

- でび まる の投稿
バカな原因わかりました。ハッキリ見えるようにと \Huge
にしてました。\LARGE, \Large など試すと何か微妙な変化が。
お騒がせしました。
でび まる への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
でびまるさん
確認ありがとうございます。ただ、私にはなぜ 「A」が上がらなく
なるのかわかっていません。一応定義を抜粋します (ltlogos.dtx):
\DeclareRobustCommand{\LaTeX}{L\kern-.36em%
        {\sbox\z@ T%
         \vbox to\ht\z@{\hbox{\check@mathfonts
                              \fontsize\sf@size\z@
                              \math@fontsfalse\selectfont
                              A}%
                        \vss}%
        }%
        \kern-.15em%
        \TeX}
aminophen への返信

Re: 数式中のボックスとベースライン補正

- でび まる の投稿
でびまるです。私が答える立場にはいませんが
\hbox に \ybaselineshift が効いてるのではないでしょうか。
発端になってる qa 54286 の返信 54294 にそれらしい記述が
あります。
理解してるわけではないので違ってたらご容赦ください。
でび まる への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
2016年 03月 01日(火曜日) 18:39
のコメントで
> (これはパッチをあてる前と後で同じです)
と書いているとおり、パッチによって qa:54286 で報告されている
「\hbox に二重のベースライン補正が効く現象」
は修正されたはずなので qa:54286 や qa:54294 とは違うと思います。
パッチをあててもなお、LaTeX のロゴが変になるということを私は
不思議に思っています。
パッチが不十分なのだろうか、それとも \vbox がだめなのだろうか?

→ 追記:よく考えてみると、これは A が \vbox に入れられているから
でしょうね。「\vbox の中の \hbox」なので、再び \hbox の中ではベース
ライン補正が効くということでしょう。お騒がせしました。
aminophen への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
> 追記:よく考えてみると、これは A が \vbox に
> 入れられているからでしょうね。
> 「\vbox の中の \hbox」なので、再び \hbox の中
> ではベースライン補正が効くということでしょう。

縦組 (tarticle) にすると、今度は A が上がりすぎますね。
\tbaselineshift20pt とかにすると、A がロゴ全体のシフト
量に追随せず、下がりきれていないのがわかります。
やっぱりよくわからないです…
aminophen への返信

Re: 数式中のボックスとベースライン補正

- でび まる の投稿
縦組で試してみました。確かに訳分りませんね(^^;
\tbaselineshift を段階的に増やしてみると、ある値を越えたら
極端に挙動が違うような印象でした。
一体何が起きてるのか皆目わかりません。
でび まる への返信

Re: 数式中のボックスとベースライン補正

- 前田 一貴 の投稿
あまり話についていけていませんが,試しに横組で

\documentclass{jarticle}
\def\T#1{%
  \ybaselineshift#1%
  \sbox0T%
  shift #1: ht \the\ht0, dp \the\dp0}
\begin{document}
\T{0pt}

\T{1pt}

\T{6pt}

\T{7pt}

\T{10pt}
\end{document}

とすると,結果は次のようになりました:

shift 0pt: ht 6.83331pt, dp 0.0pt
shift 1pt: ht 5.83331pt, dp 1.0pt
shift 6pt: ht 0.83331pt, dp 6.0pt
shift 7pt: ht 0.0pt, dp 7.0pt
shift 10pt: ht 0.0pt, dp 10.0pt

これは仕様通りなのでしょうか.
前田 一貴 への返信

Re: 数式中のボックスとベースライン補正

- 北川 弘典 の投稿
「LaTeX のロゴの『A』」のところから話が追えていませんが……,

> shift 0pt: ht 6.83331pt, dp 0.0pt
> shift 1pt: ht 5.83331pt, dp 1.0pt
> shift 6pt: ht 0.83331pt, dp 6.0pt
> shift 7pt: ht 0.0pt, dp 7.0pt
> shift 10pt: ht 0.0pt, dp 10.0pt
> これは仕様通りなのでしょうか.

pTeX は「欧文をずらす」という実装になっているので,
「和文ベースラインを基準にした時のボックスの寸法」と考えれば
そんなに不自然ではないように思えます.

「高さ(深さ)が負になる」ことはあってもいいかもしれませんが,
TeX82 の \raise, \lower とかでシフトされる場合も
高さや深さは 0 にならないので,それをに合わせたのだと思います.
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
すみません、LaTeX のロゴの「A」は
このトピック「数式中のボックスとベースライン補正」
に無関係で、私がたまたま気になったので脱線させて
しまっただけです。すみませんでした。

本題の「数式中のボックスとベースライン補正」の件は
パッチが大丈夫だと思いますので、副作用がないよう
なら取り込んでいただけるとよいと思います。
aminophen への返信

Re: 数式中のボックスとベースライン補正

- Akira Kakuto の投稿
> 本題の「数式中のボックスとベースライン補正」の件は
> パッチが大丈夫だと思いますので、副作用がないよう
> なら取り込んでいただけるとよいと思います。

r39938 として, TeX Live に代理インストール
しました。問題があったら連絡お願いします。
北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- 前田 一貴 の投稿
本題と関係ないことを知りつつ続けると,\LaTeX の例は,今の仕様だと
\sbox\z@ T から \ht\z@ の値を参照して文字の高さを取得するような
コードに対して,\ybaselineshift が 0pt でない場合に意図しない動作を
引き起こす場合があることを示唆しているのではないかと思います.

今の仕様でうまく \LaTeX を出そうとすると,例えばこんな感じでしょうか.
縦組のほうは \tbaselineshift を引かないといけない理由がよく理解できていませんが…….

\documentclass{jarticle}
\makeatletter
\DeclareRobustCommand{\LaTeX}{L\kern-.36em%
  {\def\@tempa{\check@mathfonts
        \fontsize\sf@size\z@
        \math@fontsfalse\selectfont
        A}%
    \begingroup
    \ybaselineshift0pt%
    \tbaselineshift0pt%
    \sbox\z@ T%
    \@tempdima\ht\z@
    \sbox\z@\@tempa
    \global\advance\@tempdima-\ht\z@
    \endgroup
    \iftdir
    \advance\@tempdima-\tbaselineshift % なぜ?
    \fi
    \raise\@tempdima\hbox{\@tempa}}%
  \kern-.15em%
  \TeX}
\makeatother
\begin{document}
\LaTeX ロゴ
\ybaselineshift20pt
\LaTeX ロゴ
\end{document}
前田 一貴 への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
> \LaTeX の例は,今の仕様だと
> \sbox\z@ T から \ht\z@ の値を参照して
> 文字の高さを取得するようなコードに対して,
> \ybaselineshift が 0pt でない場合に意図
> しない動作を引き起こす場合がある

これと同じ理由で意図しない動作になる例を探していて、
「\AA」も同じだと気づきました。これは縦組の場合、
デフォルトが
\tbaselineshift=3.41666pt
になっているので、○がAに重なります。

\documentclass{tarticle}
\begin{document}
あ\AA あ % ==> 異常
\tbaselineshift0pt % 比較用
あ\AA あ % ==> 正常
\end{document}

以下、私の理解:

\AA の ltplain.dtx での定義は

\def \AA {\r A}

さらに ltoutenc.dtx での定義により

\DeclareTextAccent{\r}{OT1}{23}

これは要するに

\DeclareTextCompositeCommand{\r}{OT1}{A}
{\leavevmode\setbox\z@\hbox{!}\dimen@\ht\z@\advance\dimen@-1ex%
\rlap{\raise.67\dimen@\hbox{\char23}}A}

となる。
aminophen への返信

Re: 数式中のボックスとベースライン補正

- 北川 弘典 の投稿
> これと同じ理由で意図しない動作になる例を探していて、
> 「\AA」も同じだと気づきました。これは縦組の場合、
> デフォルトが
> \tbaselineshift=3.41666pt
> になっているので、○がAに重なります。

pLaTeX 用にコードを書いてみました.
一回ベースライン補正なしの状態で組んで,
全体を後からずらすという方法をとっています.

\documentclass{tarticle}
\makeatletter
\def\@text@composite#1#2#3#{%
  \begingroup
    \setbox\z@=\hbox\bgroup%
      \ybaselineshift\z@\tbaselineshift\z@
      \expandafter\@text@composite@x
        \csname\string#1-\string#2\endcsname}
\def\@text@composite@x#1#2{%
  \ifx#1\relax
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi
  #1{#2}\egroup
  \leavevmode
  \expandafter\lower\iftdir
      \ifmdir\ybaselineshift\else\tbaselineshift\fi
    \else\ybaselineshift\fi\box\z@
\endgroup}
\makeatother
\begin{document}
漢字ABCf\AA\/DEF 漢字
\end{document}

なお,LuaTeX-ja でも同様の症状が再現しますが,
そちらについてはまた考えます.


北川 弘典 への返信

Re: 数式中のボックスとベースライン補正

- aminophen の投稿
# 脱線ではなく本題のほう…だと思ったのですが
# 以下はまだ脱線なのか本題なのかよくわかっていません…

なんだかあらさがししているみたいで申し訳ないですが

%#!platex
\documentclass{jarticle}
\begin{document}
\ybaselineshift5pt
\parindent0pt
\xkanjiskip0pt

あ$a\sqrt[2]{a}$\par
あ$a\sqrt{a}$\par

\end{document}

まだ万全ではないのかもしれません。
(添付画像:新 pTeX でも冪根の数字だけ二重シフトする)
たいして問題にはなりませんが一応報告だけです。
添付 baselineshift-11.png