Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed top and bottom alignment of CHAR mode. #5614

Merged
merged 5 commits into from
Oct 29, 2019

Conversation

caryliu1999
Copy link
Contributor

@caryliu1999 caryliu1999 commented Oct 25, 2019

问题反馈:

https://forum.cocos.com/t/2-2-0-label-cache-mode-char-vertical-align/85052

问题说明:

这个问题其实是已知的,目前2.2版本的CHAR模式沿用了BMFont的处理,对齐方式也跟BMFont一致,旧版本的BMFont的居中对齐会在节点空间位置偏下,2.2版本修正了居中对齐的效果,所以旧项目升级上来,居中对齐的BMFont位置会出现偏移。Top 跟 Bottom 对齐只是保持了旧版本的处理,这个问题之前改了几次了,只是做微调,没敢做大的改动,但是一直有用户会有不同使用情况的反馈,现在既然2.2版本已经把居中修正了,Top 跟 Bottom 也一并彻底修改了吧。

居中已经正确,该修改只是修正了 Top 跟 Bottom 的对齐,目前系统字体跟BMFont的所有对齐方式的效果全部一致。

测试验证:

这里以SHRINK模式为例:

修正之前:

image

修正之后:

居中,顶端对齐,底部对齐分别为

image

@caryliu1999
Copy link
Contributor Author

caryliu1999 commented Oct 25, 2019

补充说明:

这里涉及的文本设置情况比较多,不同排版模式,不同的节点大小与lineHeight设置,不同的文本大小与缓存模式的设置, 是否换行等等,兼容了所有不同设置,保证排版都是统一的。比如SHRINK模式下的LineHeight设置是否大于节点Size,LineHeight是否大于fontSize等。

image

@SantyWang SantyWang requested review from 2youyou2 and jareguo October 25, 2019 08:54
@SantyWang SantyWang removed the request for review from 2youyou2 October 25, 2019 09:08
Copy link
Contributor

@jareguo jareguo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

效果还是不够统一

@caryliu1999
Copy link
Contributor Author

效果还是不够统一

补充修改了 ttf 顶部与底部对齐时的留白偏移

image

if (_vAlign === macro.VerticalTextAlignment.TOP) {
firstLinelabelY = _fontSize;
firstLinelabelY = _fontSize - blank / 2;
}
else if (_vAlign === macro.VerticalTextAlignment.CENTER) {
firstLinelabelY = (_canvasSize.height - drawStartY) * 0.5 + _fontSize * textUtils.MIDDLE_RATIO - _canvasPadding.height / 2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

经过校验,修改后 (top + bottom) / 2 == center。
下面是校验过程:
TOP: (_fontSize - blank / 2 - blank / 2) / 2 = _fontSize * (0.5 - _BASELINE_RATIO / 2) = _fontSize * 0.37
BOTTOM: _fontSize * MIDDLE_RATIO = _fontSize * ((_BASELINE_RATIO + 1) / 2 - _BASELINE_RATIO) = _fontSize * 0.37

这是对的。但是这样的话,证明了这里 center 的计算和 bottom 存在冗余的地方。

假设我们提取一个变量 blank,来表达从 top 到 bottom 的距离,也就是画布上的空白高度,那么
let blank = (_canvasSize.height - drawStartY - blank / 2 - _canvasPadding.height) - (_fontSize - blank / 2);
= _canvasSize.height - drawStartY - _canvasPadding.height - _fontSize;

// TOP
let firstLinelabelY = _fontSize * (1 - textUtils.BASELINE_RATIO / 2);
if (_vAlign !== macro.VerticalTextAlignment.TOP) {
  // free space in vertical direction
  let blank = _canvasSize.height - drawStartY - _canvasPadding.height - _fontSize;
  if (_vAlign === macro.VerticalTextAlignment.BOTTOM) {
    // BOTTOM
    firstLinelabelY -= blank;
  }
  else {
    // CENTER
    _letterOffsetY -= blank / 2;
  }
}

这样一来计算结果是一致的,但是要计算的情况从 3 种变成了 2 种。避免了之前出现的 center 结果正确,但是 top 和 bottom 偏移了的情况。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

根据同样的思路,BMFont 那边 blank 应该改为 _contentSize.height - _textDesiredHeight + (_lineHeight - _originFontSize) * _bmfontScale
BMFont 的 BOTTOM 和 CENTER 代码不用改。

可以看出 blank 和 ttf 的 blank 的计算是差不多的,之后还可以考虑进一步算法融合。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

最后,ttf 和 bmfont 的 blank,是不是都应该限制不能小于 0 ?否则又会出现 top 比 bottom 还要低的情况

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

经过校验,修改后 (top + bottom) / 2 == center。
下面是校验过程:
TOP: (_fontSize - blank / 2 - blank / 2) / 2 = _fontSize * (0.5 - _BASELINE_RATIO / 2) = _fontSize * 0.37
BOTTOM: _fontSize * MIDDLE_RATIO = _fontSize * ((_BASELINE_RATIO + 1) / 2 - _BASELINE_RATIO) = _fontSize * 0.37

这是对的。但是这样的话,证明了这里 center 的计算和 bottom 存在冗余的地方。

假设我们提取一个变量 blank,来表达从 top 到 bottom 的距离,也就是画布上的空白高度,那么
let blank = (_canvasSize.height - drawStartY - blank / 2 - _canvasPadding.height) - (_fontSize - blank / 2);
= _canvasSize.height - drawStartY - _canvasPadding.height - _fontSize;

// TOP
let firstLinelabelY = _fontSize * (1 - textUtils.BASELINE_RATIO / 2);
if (_vAlign !== macro.VerticalTextAlignment.TOP) {
  // free space in vertical direction
  let blank = _canvasSize.height - drawStartY - _canvasPadding.height - _fontSize;
  if (_vAlign === macro.VerticalTextAlignment.BOTTOM) {
    // BOTTOM
    firstLinelabelY -= blank;
  }
  else {
    // CENTER
    _letterOffsetY -= blank / 2;
  }
}

这样一来计算结果是一致的,但是要计算的情况从 3 种变成了 2 种。避免了之前出现的 center 结果正确,但是 top 和 bottom 偏移了的情况。

已修改合并了一部分ttf的计算

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

最后,ttf 和 bmfont 的 blank,是不是都应该限制不能小于 0 ?否则又会出现 top 比 bottom 还要低的情况

限制之后会影响其他一些情况下的偏移。

image

这种极端使用情况,效果其实是正常的,就是Top是对齐上边缘,Bottom是对齐下边缘,这种情况下,Bottom对齐的位置是会比Top对齐的位置高,因为我们本身就是以边缘对齐为准的。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

明白,有道理

@jareguo
Copy link
Contributor

jareguo commented Oct 26, 2019

麻烦试一下 runtime 平台的效果,因为 rumtime 的 BASELINE_RATIO 值不一样,怕修改后会出问题

@caryliu1999
Copy link
Contributor Author

已修改合并了一部分ttf的计算

麻烦试一下 runtime 平台的效果,因为 rumtime 的 BASELINE_RATIO 值不一样,怕修改后会出问题

runtime 平台的我这里没有环境,可能需要测试组或者runtime那边帮助测试一下是否正常。

@jareguo jareguo merged commit 03de0df into cocos:v2.2.1-release Oct 29, 2019
@caryliu1999 caryliu1999 deleted the v2.2.1-release-align branch June 22, 2021 03:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants