<commit_before>from fontTools.misc.textTools import bytesjoin, safeEval, readHex
from fontTools.misc.encodingTools import getEncoding
from fontTools.ttLib import getSearchRange
from fontTools.unicode import Unicode
from . import DefaultTable
import sys
import struct
import array
import logging


log = logging.getLogger(__name__)


def _make_map(font, chars, gids):
	assert len(chars) == len(gids)
	glyphNames = font.getGlyphNameMany(gids)
	cmap = {}
	for char,gid,name in zip(chars,gids,glyphNames):
		if gid == 0:
			continue
		cmap[char] = name
	return cmap

class table__c_m_a_p(DefaultTable.DefaultTable):
	"""Character to Glyph Index Mapping Table

	This class represents the `cmap <https://docs.microsoft.com/en-us/typography/opentype/spec/cmap>`_
	table, which maps between input characters (in Unicode or other system encodings)
	and glyphs within the font. The ``cmap`` table contains one or more subtables
	which determine the mapping of of characters to glyphs across different platforms
	and encoding systems.

	``table__c_m_a_p`` objects expose an accessor ``.tables`` which provides access
	to the subtables, although it is normally easier to retrieve individual subtables
	through the utility methods described below. To add new subtables to a font,
	first determine the subtable format (if in doubt use format 4 for glyphs within
	the BMP, format 12 for glyphs outside the BMP, and format 14 for Unicode Variation
	Sequences) construct subtable objects with ``CmapSubtable.newSubtable(format)``,
	and append them to the ``.tables`` list.

	Within a subtable, the mapping of characters to glyphs is provided by the ``.cmap``
	attribute.

	Example::

		cmap4_0_3 = CmapSubtable.newSubtable(4)
		cmap4_0_3.platformID = 0
		cmap4_0_3.platEncID = 3
		cmap4_0_3.language = 0
		cmap4_0_3.cmap = { 0xC1: "Aacute" }

		cmap = newTable("cmap")
		cmap.tableVersion = 0
		cmap.tables = [cmap4_0_3]
	"""

	def getcmap(self, platformID, platEncID):
		"""Returns the first subtable which matches the given platform and encoding.

		Args:
			platformID (int): The platform ID. Use 0 for Unicode, 1 for Macintosh
				(deprecated for new fonts), 2 for ISO (deprecated) and 3 for Windows.
			encodingID (int): Encoding ID. Interpretation depends on the platform ID.
				See the OpenType specification for details.

		Returns:
			An object which is a subclass of :py:class:`CmapSubtable` if a matching
			subtable is found within the font, or ``None`` otherwise.
		"""

		for subtable in self.tables:
			if (subtable.platformID == platformID and
					subtable.platEncID == platEncID):
				return subtable
		return None # not found

	def getBestCmap(self, cmapPreferences=((3, 10), (0, 6), (0, 4), (3, 1), (0, 3), (0, 2), (0, 1), (0, 0))):
		"""Returns the 'best' Unicode cmap dictionary available in the font
		or ``None``, if no Unicode cmap subtable is available.

		By default it will search for the following (platformID, platEncID)
		pairs in order::

				(3, 10), # Windows Unicode full repertoire
				(0, 6),  # Unicode full repertoire (format 13 subtable)
				(0, 4),  # Unicode 2.0 full repertoire
				(3, 1),  # Windows Unicode BMP
				(0, 3),  # Unicode 2.0 BMP
				(0, 2),  # Unicode ISO/IEC 10646
				(0, 1),  # Unicode 1.1
				(0, 0)   # Unicode 1.0

		This order can be customized via the ``cmapPreferences`` argument.
		"""
		for platformID, platEncID in cmapPreferences:
			cmapSubtable = self.getcmap(platformID, platEncID)
			if cmapSubtable is not None:
				return cmapSubtable.cmap
		return None  # None of the requested cmap subtables were found

	def buildReversed(self):
		"""Builds a reverse mapping dictionary

		Iterates over all Unicode cmap tables and returns a dictionary mapping
		glyphs to sets of codepoints, such as::

			{
				'one': {0x31}
				'A': {0x41,0x391}<commit_msg>[cmap] Document rationale for getBestCmap choice of subtable<commit_after>from fontTools.misc.textTools import bytesjoin, safeEval, readHex
from fontTools.misc.encodingTools import getEncoding
from fontTools.ttLib import getSearchRange
from fontTools.unicode import Unicode
from . import DefaultTable
import sys
import struct
import array
import logging


log = logging.getLogger(__name__)


def _make_map(font, chars, gids):
	assert len(chars) == len(gids)
	glyphNames = font.getGlyphNameMany(gids)
	cmap = {}
	for char,gid,name in zip(chars,gids,glyphNames):
		if gid == 0:
			continue
		cmap[char] = name
	return cmap

class table__c_m_a_p(DefaultTable.DefaultTable):
	"""Character to Glyph Index Mapping Table

	This class represents the `cmap <https://docs.microsoft.com/en-us/typography/opentype/spec/cmap>`_
	table, which maps between input characters (in Unicode or other system encodings)
	and glyphs within the font. The ``cmap`` table contains one or more subtables
	which determine the mapping of of characters to glyphs across different platforms
	and encoding systems.

	``table__c_m_a_p`` objects expose an accessor ``.tables`` which provides access
	to the subtables, although it is normally easier to retrieve individual subtables
	through the utility methods described below. To add new subtables to a font,
	first determine the subtable format (if in doubt use format 4 for glyphs within
	the BMP, format 12 for glyphs outside the BMP, and format 14 for Unicode Variation
	Sequences) construct subtable objects with ``CmapSubtable.newSubtable(format)``,
	and append them to the ``.tables`` list.

	Within a subtable, the mapping of characters to glyphs is provided by the ``.cmap``
	attribute.

	Example::

		cmap4_0_3 = CmapSubtable.newSubtable(4)
		cmap4_0_3.platformID = 0
		cmap4_0_3.platEncID = 3
		cmap4_0_3.language = 0
		cmap4_0_3.cmap = { 0xC1: "Aacute" }

		cmap = newTable("cmap")
		cmap.tableVersion = 0
		cmap.tables = [cmap4_0_3]
	"""

	def getcmap(self, platformID, platEncID):
		"""Returns the first subtable which matches the given platform and encoding.

		Args:
			platformID (int): The platform ID. Use 0 for Unicode, 1 for Macintosh
				(deprecated for new fonts), 2 for ISO (deprecated) and 3 for Windows.
			encodingID (int): Encoding ID. Interpretation depends on the platform ID.
				See the OpenType specification for details.

		Returns:
			An object which is a subclass of :py:class:`CmapSubtable` if a matching
			subtable is found within the font, or ``None`` otherwise.
		"""

		for subtable in self.tables:
			if (subtable.platformID == platformID and
					subtable.platEncID == platEncID):
				return subtable
		return None # not found

	def getBestCmap(self, cmapPreferences=((3, 10), (0, 6), (0, 4), (3, 1), (0, 3), (0, 2), (0, 1), (0, 0))):
		"""Returns the 'best' Unicode cmap dictionary available in the font
		or ``None``, if no Unicode cmap subtable is available.

		By default it will search for the following (platformID, platEncID)
		pairs in order::

				(3, 10), # Windows Unicode full repertoire
				(0, 6),  # Unicode full repertoire (format 13 subtable)
				(0, 4),  # Unicode 2.0 full repertoire
				(3, 1),  # Windows Unicode BMP
				(0, 3),  # Unicode 2.0 BMP
				(0, 2),  # Unicode ISO/IEC 10646
				(0, 1),  # Unicode 1.1
				(0, 0)   # Unicode 1.0

		This particular order matches what HarfBuzz uses to choose what
		subtable to use by default. This order prefers the largest-repertoire
		subtable, and among those, prefers the Windows-platform over the
		Unicode-platform as the former has wider support.

		This order can be customized via the ``cmapPreferences`` argument.
		"""
		for platformID, platEncID in cmapPreferences:
			cmapSubtable = self.getcmap(platformID, platEncID)
			if cmapSubtable is not None:
				return cmapSubtable.cmap
		return None  # None of the requested cmap subtables were found

	def buildReversed(self):
		"""Builds a reverse mapping dictionary

		Iterates over all Unicode cmap tables and returns a dictionary mapping
		glyphs to sets of codepoints, such as::

			{
				'one': {0x31}
				'A': {0x41,0x391}
{'fraction_non_alphanumeric': 0.08725849223386792, 'fraction_numerical': 0.023740371258997348, 'mean_word_length': 4.070422535211268, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1351659', 'n_tokens_mistral': 2868, 'n_tokens_neox': 2457, 'n_words': 972}