# Shifting baseline of CJK characters

I'm using XeLaTeX with the xeCJK package for typesetting Chinese. I've set the Songti SC font on macOS as the main font, while also using Heiti SC and Fangsong in some places.

I've noticed that characters in Songti SC has a lower baseline than other characters, as seen in the image below: where the red line is the baseline for English characters. (The line and font name are added using image editing software)

Basically, my question is: How could I shift the baseline of only Songti SC characters?

Here's a flaw implementation that I came up with. I modified the code snippet from Vertical Chinese text that contains characters in a "CJK fallback family font", and here's a minimum working example:

\documentclass{minimal}
\usepackage{xeCJK}
\usepackage{xpatch}

% Define fonts
\setCJKmainfont{Songti SC}
\newCJKfontfamily\heiti{Heiti SC}
\newCJKfontfamily\fangsong{FangSong}

% Raise the baseline of Songti SC characters by 0.05em
% This is done by wrapping every CJK character in a raisebox
\makeatletter
\let\original@CJKsymbol\CJKsymbol
\let\original@CJKpunctsymbol\CJKpunctsymbol
\edef\CJKmovesymbol#1{\raise.05em\hbox{\original@CJKsymbol{#1}}}
\edef\CJKmovepunctsymbol#1{\raise.05em\hbox{\original@CJKpunctsymbol{#1}}}
% Only shift non-puncts because puncts seems in their place
\def\CJKraisebaseline{%
\let\CJKsymbol\CJKmovesymbol
}
\def\CJKresetbaseline{%
\let\CJKsymbol\original@CJKsymbol
}
% When switching to Heiti and FangSong, revert settings
\xpretocmd\heiti{\CJKresetbaseline}{}{}
\xpretocmd\fangsong{\CJKresetbaseline}{}{}
\makeatother

% Activate!
\CJKraisebaseline

\begin{document}

{\heiti 这是黑体：}这是$a^b_c$宋体（This is $a^b_c$ English）{\fangsong 这是仿宋}

\end{document}


which produces:

This works pretty well, except that the space between CJK characters and inline maths is missing. I tried fixing this using:

\everymath{~}


but this also changes display style math as well, and also adds one extra space to maths surrounded by English characters.

So my question is: Is there any way to fix this problem? Or maybe, is there is better approach to the baseline-shifting problem?

• You may consider this answer: tex.stackexchange.com/a/11916/136923. However, the end-line characters will not be ignored automatically with such patch, so it's necessary (but cumbersome) to add some % at the end of specific lines. – stone-zeng Jul 17 '18 at 3:09
• @Stone-Zeng Thanks for the comment! The approach mentioned in the answer is actually what I have been using in the code above. The problem is that this approach does not preserve the space between a CJK character and inline math, which I assume is due to xeCJK not recognizing they're adjacent so stuff like "ecglue" is not working. – Zecong Hu Jul 17 '18 at 13:16