Stacked combining diacritics and CoreText Harfbuzz differences

I have run into the following issue: I am trying to setup stacking diacritics by using ccmp and combining diacritics. It works as expected in CoreText (in this example it’s for UC base-glyphs)

But in Harfbuzz I get the U and the dieresiscomb.case substituted by Udieresis, and then the additional combining diacritics.

I there a way to make Harfbuzz not do this? (Or do I have it the wrong way around and Harfbuzz is actually doing it right?)

That is Unicode normalization being applied. When and in what direction (some other app might decompose a directly typed Udieresis) this is applied is not consistent.
You need to decompose the Udieresis anyway as someone could have typed it directly.

HarfBuzz always prefers the NFC (composed) form if the font supports it. You will have to decompose the composed forms in ccmp feature if you want to work only with decomposed form.

HarfBuzz also changes the order of the marks to the canonical order (with exceptions in Arabic and Hebrew because the canonical order there is plain broken).

Right, thank you for the explanation. I’m not going to mess with this and work around it. That feels better in this particular case. But it does lead me to the next issue then, which is why the Glyphs automatic ccmp feature substitutes LC combining diacritics with the UC forms when I stack combining diacritics. I shall mention that I have not set the Use case marks for double marks custom parameter. In this particular design I do not want UC diacritics on the LC glyphs.

lookup ccmp_DFLT_1 {
	@CombiningTopAccents = [acutecomb brevecomb caroncomb circumflexcomb dieresiscomb dotaccentcomb gravecomb hungarumlautcomb macroncomb ringcomb tildecomb];
	lookupflag UseMarkFilteringSet @CombiningTopAccents;
	sub i' @CombiningTopAccents by idotless;
	sub j' @CombiningTopAccents by jdotless;
} ccmp_DFLT_1;

lookup ccmp_Other_1 {
	lookupflag 0;
	@Markscomb = [dieresiscomb dotaccentcomb gravecomb acutecomb hungarumlautcomb circumflexcomb caroncomb brevecomb ringcomb tildecomb macroncomb commaaccentcomb cedillacomb ogonekcomb dieresis dotaccent grave acute hungarumlaut circumflex caron breve ring tilde macron cedilla ogonek];
	@MarkscombCase = [dieresiscomb.case dotaccentcomb.case gravecomb.case acutecomb.case hungarumlautcomb.case circumflexcomb.case caroncomb.case brevecomb.case ringcomb.case tildecomb.case macroncomb.case commaaccentcomb.case cedillacomb.case ogonekcomb.case dieresis.case dotaccent.case grave.case acute.case hungarumlaut.case circumflex.case caron.case breve.case ring.case tilde.case macron.case cedilla.case ogonek.case];
	sub @Markscomb @Markscomb' by @MarkscombCase;
	sub @Uppercase @Markscomb' by @MarkscombCase;
} ccmp_Other_1;

lookup ccmp_Other_2 {
	lookupflag 0;
	sub @Markscomb' @MarkscombCase by @MarkscombCase;
	sub @MarkscombCase @Markscomb' by @MarkscombCase;
} ccmp_Other_2;

Ping @GeorgSeifert See my post above: Why are the combining diacritics replaced with the .case variants on lower-case base-glyphs?

Georg you haven’t responded to my question. Please do so, and also let me know about this idea: I want to use the case variant combining diacritics for all instances of stacked diacritics. That means I need to decompose all the accented minuscule glyphs and replace them with a string of base glyph + combining case variant diacritic + combining case variant diacritic + … The question is if I hard-code this in the ccmp feature? Will that play with Glyphs?

IIRC dates back to a specific user request. Apparently this is common practice among people who stack accents, assuming that the .case variant is a bit more space-saving.

Maybe I do not entirely understand the question but I don’t think Glyphs is the issue here. It lets you put anything into ccmp. The issue will be the environments that still do not (sufficiently) support ccmp.

I’m asking because of the semi-secret custom parameter Use case marks for double marks which I can’t get to function, meaning whatever I set it to stacked marks are case variants.

I’m way ahead of you here. The case is that sometimes you need them to be more vertically compact, but sometimes the case variants are too wide for use on lower-case.

What I want is basically just for that custom parameter to actually work, and for Glyphs not to do this case variant substitution without being told to do so.

I made my own ccmp feature to handle this, but Glyphs is sabotaging it. Plus there are some corner cases with strings of pre-composed double-stacked characters that are not in the font – what happens then when I start decomposing and substituting for case variants – I can’t test it because Glyphs does automatic stuff I can’t control.

How?