Android三星设备Noto简体中文字体行高计算异常问题求解
三星设备Noto字体行高计算偏移问题
问题背景
我正在开发一款每行文本对应配置一个复选框的编辑器控件,近期在计算字体行高时遇到异常,问题涉及的目标字体为 NotoSansMonoCJKSC-Regular.otf。
我将该字体与consola.ttf(Consolas)字体做了对照测试,可明显观察到中文字符会逐渐下滑偏移至参考线下方。
补充场景说明:该问题仅在三星品牌手机上复现,在联想平板、小米手机上运行逻辑无异常,替换为SimHei中文字体时显示也正常。
相关测试效果截图:
- Noto简体中文字体显示效果
- Consolas字体显示效果
初始实现代码
OnDraw 方法实现
EditorRenderer中编写的绘制逻辑如下:
protected override void OnDraw(Canvas canvas) { int height = (int)GetLineHeight(Utils.SizeUnits.px); int movingBaseline = Control.Baseline + CHECK_BOTTOM_MARGIN; int scrollY = Control.ScrollY; CheckBox cb; if (!_checks.CoordsSet) _checks.Init(Control.Baseline, height); for (int i = 0; i < _checks.Count; i++) { cb = _checks[i]; if (!_checks.CoordsSet) cb.Init(movingBaseline); canvas.DrawRect(cb.Rect.Left, cb.Rect.Top - scrollY, cb.Rect.Right, cb.Rect.Bottom - scrollY, _checks.GetPaint(i)); //font height debug canvas.DrawLine(cb.Rect.Left, cb.Rect.Bottom - scrollY, cb.Rect.Left + Control.Width, cb.Rect.Bottom - scrollY, checks.PaintCheckSolid); movingBaseline = Control.Baseline + CHECK_BOTTOM_MARGIN + (height * (i + 1)); } _checks.CoordsSet = true; base.OnDraw(canvas); }
行高计算逻辑
当前通过以下两个方法实现行高计算:
protected double GetLineHeight(SizeUnits units = SizeUnits.dp) { return (CalculateLineHeight(editor, units) * _lineSpacingFactor) + _lineAddedPixels; } public double CalculateLineHeight(EditorEx editor, SizeUnits units) { Paint.FontMetrics fm = editor.AndroidTextView.Paint.GetFontMetrics(); return (fm.Descent - fm.Ascent) / (units == SizeUnits.px ? 1 : Resources.System.DisplayMetrics.ScaledDensity); }
初始疑问:上述实现逻辑存在什么问题?
问题更新
我根据此前收到的答复调整了实现,尽可能使用double类型处理数值,仅在方法参数强制要求类型时才转换为int或float,调整后的OnDraw方法代码如下:
protected override void OnDraw(Canvas canvas) { double height = GetLineHeight(Utils.SizeUnits.px); double movingBaseline = (double)Control.Baseline + CHECK_BOTTOM_MARGIN; double scrollY = (double)Control.ScrollY; CheckBox cb; if (!_checks.CoordsSet) _checks.Init(Control.Baseline, height); for (int i = 0; i < _checks.Count; i++) { cb = _checks[i]; if (!_checks.CoordsSet) cb.Init(movingBaseline); canvas.DrawRect((float)cb.Rect.Left, (float)(cb.Rect.Top - scrollY), (float)cb.Rect.Right, (float)(cb.Rect.Bottom - scrollY), _checks.GetPaint(i)); //font height debug canvas.DrawLine((float)cb.Rect.Left, (float)(cb.Rect.Bottom - scrollY), (float)(cb.Rect.Left + Control.Width), (float)(cb.Rect.Bottom - scrollY), _checks.PaintCheckSolid); movingBaseline = (double)Control.Baseline + CHECK_BOTTOM_MARGIN + (height * (double)(i + 1)); } _checks.CoordsSet = true; base.OnDraw(canvas); }
但调整后问题并未解决,对应异常效果有留存截图,当前疑问:是否有其他排查方向或解决方案?
内容的提问来源于stack exchange,提问作者jho
相关产品推荐
相关产品推荐

