Skip to content

Generate decrypt strings for unknown CG fonts#22

Open
elewing wants to merge 1 commit into
dteviot:masterfrom
elewing:2173
Open

Generate decrypt strings for unknown CG fonts#22
elewing wants to merge 1 commit into
dteviot:masterfrom
elewing:2173

Conversation

@elewing

@elewing elewing commented Jul 9, 2026

Copy link
Copy Markdown
  • Adds opentype script https://github.com/opentypejs/opentype.js
  • Also loads https://github.com/fontello/wawoff2 on demand to decompress woff2 fonts per instructions in Opentype README
  • In the Clean Chrysanthemum Garden method, pulls fonts from loaded epub and generates a decrypt string to pass to the existing decrypt method using the glyph paths in the font, which we are assuming are always the same.

dteviot/WebToEpub#2173 (comment)

@gamebeaker

Copy link
Copy Markdown
Collaborator

@elewing interesting. Did you have a look here #21? (I added in the PR wawoff2_decompress_binding.js so we don't need to load it from the internet) (Ithink there are issues with scripts from the Internet if you just open the HTML as a file in the browser but i am not sure.)

Can you elxplain what glyphToCharMapping does? where did you get the keys from?

@elewing

elewing commented Jul 9, 2026

Copy link
Copy Markdown
Author

Oh, I must have missed that part of the method when I was looking earlier! I did some testing using the local HTML file and didn't see issues, but happy to update to add the scripts locally in the same way if that's best practice.

Apologies if I'm explaining things you already know, but for context, the way the fonts are set up, each glyph is mapped to the "scrambled" unicode character rather than its actual displayed character. In order to decrypt it, we have been defining a "decrypt string" which maps the appearance of each glyph (e.g. the actual displayed character), which is defined by its path, to its unicode value/the character it says it is. So, in order to automate that decryption process, all that is necessary is to have some way to identify what the glyph actually is rather than the unicode character it is declaring it is, then map it to our expected format for calling decrypt. Because the font is actually the same with just scrambled unicode values, the paths for each glyph are static and will be the same regardless of their order in any one font -- e.g. the glyph path for "a" will always be the same and can be reliably mapped to "a" automatically.

I got those glyph paths by opening a sample font from a CG epub and logging the path of each glyph in the console, then mapping them to their actual displayed character the same way we have been doing to manually create these decryption strings. This should work for any font as long as it uses the same base glyphs, though I'd expect it to break if CG changed their underlying font style (though that doesn't seem to have happened thus far).

@gamebeaker

Copy link
Copy Markdown
Collaborator

@elewing thanks for the explanation. I understood it like this:

Normally it works like this. (The values aren't real)

Binary Font Lookup Display svg for font character
0x01 Let me get the first Char of the Font Display the Char from the font (looks like an "A")
0x02 Let me get the second Char of the Font Display the Char from the font (looks like an "B")

You now extracted the Binary representation from "Display svg for font character" and can now make a reverse lookup.

Binary representation of the svg font -> what real world char is that? -> override original Binary (text)
That only works as long as they use the exact same Binary svg for all their custom fonts.

Very elegant. Is better than my solution witch maps the custom fonts. Your solution works for tts/ search etc.

I would keep my solution as https://requiemtls.com/ also uses custom fonts. (And in case they set one pixel in the future different for each font my solution would still work as a backup.)

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.

2 participants