panda3d icon indicating copy to clipboard operation
panda3d copied to clipboard

text: add 'small_caps' functionality to harfbuzz

Open derpydraggo opened this issue 1 year ago • 4 comments

Issue description

This commit attempts to resolve issue #1666 (which was introduced when building with harfbuzz after commit 0dad38d), by adding code in TextAssembler.shape_buffer(), to handle the case where:

  1. harfbuzz is built with the engine
  2. is wanted via the config variable text-use-harfbuzz being set to true, and
  3. the TextProperties associated with the to-be-drawn text also has the small_caps field set.

Solution description

If the above cases are all true, then the buffer is first remade with all harfbuzz 'codepoints' switched to the uppercase variant (if needed and possible), while keeping the harfbuzz 'cluster' value the same for tracking what characters need their scaling changed. Later when the glyphs are actually in the process of being generated, I check to see if those earlier 'cluster' values are lowercase values, and go ahead and use individual scale values for each character, using get_small_caps_scale() for these characters instead of the usual get_glyph_scale() in every other case.

Checklist

I have done my best to ensure that…

  • [x] …I have familiarized myself with the CONTRIBUTING.md file
  • [x] …this change follows the coding style and design patterns of the codebase
  • [x] …I own the intellectual property rights to this code
  • [x] …the intent of this change is clearly explained
  • [x] …existing uses of the Panda3D API are not broken
  • [x] …the changed code is adequately covered by the test suite, where possible.

derpydraggo avatar Jul 02 '24 05:07 derpydraggo

Should we not try and pass the smcp feature to hb_shape to use the native small caps support if provided by the font?

Oh? I was not aware of that feature (sorry, this is perhaps the first time I'm actually tinkering with harfbuzz and Unicode character handling in general).

I'll go and make those changes (including changing has_small_caps() to get_small_caps()!

derpydraggo avatar Jul 03 '24 00:07 derpydraggo

Well, I've commented out my original code while experimenting, and while I do believe the code I wrote to use the smcp feature seems to work,

std::vector<hb_feature_t> hb_shape_feats;
if (properties.get_small_caps()) {
  hb_feature_t tmp_feat;
  tmp_feat.tag = HB_TAG('s', 'm', 'c', 'p');
  tmp_feat.value = 1;
  tmp_feat.start = HB_FEATURE_GLOBAL_START;
  tmp_feat.end = HB_FEATURE_GLOBAL_END;

  hb_shape_feats.push_back(tmp_feat);
}

if (hb_shape_feats.size() > 0) {
  hb_shape(hb_font, buf, hb_shape_feats.data(), hb_shape_feats.size());
} else {
  hb_shape(hb_font, buf, nullptr, 0);
}

it does not seem to do anything in the demo code provided in issue #1666. I'm trying to look into this further, and if it's possible for me to query the font to see if it has small caps support.

derpydraggo avatar Jul 03 '24 04:07 derpydraggo

What's the current status of this?

rdb avatar Oct 16 '24 11:10 rdb

I've been dealing with personal issues for a while, and I'm not sure at this time when I can continue looking into this.

derpydraggo avatar Oct 18 '24 04:10 derpydraggo

No worries. I'll finish the work and push it shortly. Will be part of 1.10.15. Thanks for looking into all this!

I looked into smcp and only some fonts supported it. The first font I tried (Inter) actually only supported it for some glyphs, creating a strange result. So, I think we're just going to do our own scaling, and maybe revisit smcp in the future.

rdb avatar Oct 31 '24 13:10 rdb