<div dir="ltr"><div>Hello all,</div><div><br></div><div>Sorry about this commit message, I'm still getting used to monticello apparently.</div><div>  <br></div><div>This commit deals with being able to render Unicode fonts that are in the higher codepoint planes. Here are two commit messages I had locally that explain it:</div><div>  <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Initial implementation of cmap format 12 from the ttf spec.</div><div><br></div><div>Modifying font reading to better conform with apple's TTF guidelines. In two ways.<br>  <br>First, Windows platform with encoding id 10 is actually a Unicode platform, so TTCharacterMappingTable will now have isUnicode respond true for such cases.<br>  <br>Second, the TTF spec (<a href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html">https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html</a>) says that *not only* should Unicode cmaps be preferred, but those with character encodings outside of the Unicode BMP (aka the base multilingual plane) should be preferred above all. We modify #processCharMap: here to try and determine the best Unicode mapping to use in the case of multiple options. For now, we simply pick the one with the larger character table.</div></blockquote></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 8, 2022 at 8:33 AM <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">A new version of TrueType was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/TrueType-EG.72.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/inbox/TrueType-EG.72.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: TrueType-EG.72<br>
Author: EG<br>
Time: 8 February 2022, 8:22:21.647553 am<br>
UUID: 30a1fb32-8d4c-45f6-853d-4b6727e2149c<br>
Ancestors: TrueType-EG.71<br>
<br>
Removing leftover halt message<br>
<br>
=============== Diff against TrueType-mt.68 ===============<br>
<br>
Item was changed:<br>
  ----- Method: TTCharacterMappingTable>>isUnicode (in category 'testing') -----<br>
  isUnicode<br>
<br>
+       "A cmap is considered Unicode if either:<br>
+        a) the platformID is 0, ie the Unicode platform; or<br>
+        b) The platformID is Windows (3) and the encodingID is Unicode for Windows (10).<br>
+        See the 'cmap encoding subtables' section of <a href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html" rel="noreferrer" target="_blank">https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html</a>"<br>
+       ^ (platformID = 0) or: [<br>
+               (platformID = 3 and: [ encodingID = 10 ])]!<br>
-       ^ platformID = 0!<br>
<br>
Item was added:<br>
+ ----- Method: TTFontReader>>decodeCmapFmtTable12: (in category 'private') -----<br>
+ decodeCmapFmtTable12: entry<br>
+       "Segmented coverage for supplementary range unicode chars.<br>
+       See <a href="https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table</a>"<br>
+       | length language numGroups cmap groups |<br>
+       entry nextUShort. "This is ignored, so we now align to 32-bit values"<br>
+       length := entry nextULong.<br>
+       language := entry nextULong.<br>
+       numGroups := entry nextULong.<br>
+       groups := Array new: numGroups.<br>
+       <br>
+       1 to: numGroups do: [ :num |<br>
+               groups at: num put: {<br>
+                       entry nextULong. "startCharCode"<br>
+                       entry nextULong. "endCharCode"<br>
+                       entry nextULong. "startGlyphId"<br>
+                       0. "End glyph id will be calculated"}].<br>
+               <br>
+       "Groups are in order, so the last group's endCharcode is<br>
+       the full size of the character map"<br>
+       cmap := Array new: (groups last second + 1) withAll: 0.<br>
+       <br>
+       groups do: [ :groupData |<br>
+               | codeStart codeEnd |<br>
+               codeStart := groupData first.<br>
+               codeEnd := groupData second.<br>
+               codeStart to: codeEnd do: [ :index |<br>
+                       cmap at: (index + 1) put: (groupData third + (index - codeStart))]].<br>
+ <br>
+       ^ {language. cmap}<br>
+       !<br>
<br>
Item was changed:<br>
  ----- Method: TTFontReader>>decodeCmapFmtTable: (in category 'private') -----<br>
  decodeCmapFmtTable: entry<br>
        "Decode cmap table. Currently supports formats 0, 4, and 6<br>
        <a href="https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table" rel="noreferrer" target="_blank">https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table</a>"<br>
<br>
        | cmapFmt |<br>
        ^ (cmapFmt := entry nextUShort)<br>
                caseOf: {<br>
                        [0] -> [self decodeCmapFmtTable0: entry].<br>
                        [4] -> [self decodeCmapFmtTable4: entry].<br>
                        [6] -> [self decodeCmapFmtTable6: entry].<br>
+                       [12] -> [self decodeCmapFmtTable12: entry].<br>
                } otherwise: [<br>
                        Transcript showln: '[TTFontReader] Unsupported encoding of cmap: ', cmapFmt.<br>
                        {nil.nil}]!<br>
<br>
Item was changed:<br>
  ----- Method: TTFontReader>>processCharMap: (in category 'processing - support') -----<br>
  processCharMap: mappingTables<br>
        "Process the given character map. Prefer Unicode mappings"<br>
+       "According to <a href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html" rel="noreferrer" target="_blank">https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html</a><br>
+       we should not only prefer Unicode cmaps, but should prioritize cmaps not restricted to BMP. Therefore<br>
+       if there are multiple Unicode maps we need to select the first best option"<br>
<br>
+       "^ mappingTables<br>
-       ^ mappingTables<br>
                detect: [:ea | ea isUnicode]<br>
                ifFound: [:table | table map: glyphs]<br>
+               ifNone: [mappingTables last map: glyphs]"<br>
+       <br>
+       | unicode result |<br>
+       unicode := mappingTables select: [ :cmap | cmap isUnicode ].<br>
+       unicode size = 1 ifTrue: [ ^ unicode first map: glyphs ].<br>
+       unicode size = 0 ifTrue: [ ^ mappingTables last map: glyphs ].<br>
+       <br>
+       "Otherwise, we have multiple Unicode maps. In lieu of selecting<br>
+       the one not restricted to BMP, we pick the one with the largest<br>
+       character range. There might be a better way to handle this."<br>
+       result := unicode first.<br>
+       unicode do: [ :cmap |<br>
+               cmap characterMap size > result characterMap size<br>
+                       ifTrue: [ result := cmap]].<br>
+       ^ result map: glyphs!<br>
-               ifNone: [mappingTables last map: glyphs]!<br>
<br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Eric</div></div></div>