Skip to content

Commit

Permalink
Dropped hyperglot dependency due to licensing.
Browse files Browse the repository at this point in the history
 - Removed SupportedLanguages method as it relies on hyperglot, which is under the GPLv3, to keep gftranslate under Apache 2.0
 - The method is still available as a separate code-snippet (not part of gflanguages itself), and any program using that snippet will need to comply with the GPLv3.
 - For more details, see: fonttools/fontbakery#3617 (comment)
  • Loading branch information
felipesanches committed Feb 18, 2022
1 parent 30c13b8 commit 3c8aa2e
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 65 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
Below are the most important changes from each release.

## 0.2.0 (2022-Feb-18)
### Release notes
- dropped hyperglot dependency due to licensing. See below.
- Removed SupportedLanguages method as it relies on hyperglot, which is under the GPLv3, to keep gftranslate under Apache 2.0
- The method is still available as a separate code-snippet (not part of gflanguages itself), and any program using that snippet will need to comply with the GPLv3.
- For more details, see: https://github.com/googlefonts/fontbakery/pull/3617#issuecomment-1044898812


## 0.1.1 (2022-Feb-18)
### Bugfix
- updated and simplified the textproto definition to workaround this kind of problem when using the module on projects that also import `fonts_public_pb2.py`: https://github.com/protocolbuffers/protobuf/issues/3002
Expand Down
45 changes: 0 additions & 45 deletions Lib/gflanguages/lang_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,14 @@
import glob
import os

from fontTools.ttLib import TTFont
from google.protobuf import text_format
from hyperglot import parse as hyperglot_parse
from pkg_resources import resource_filename

from gflanguages import languages_public_pb2

DATA_DIR = resource_filename("gflanguages", "data")


def _ParseFontChars(path):
"""
Open the provided font path and extract the codepoints encoded in the font
@return list of characters
"""
font = TTFont(path, lazy=True)
cmap = font["cmap"].getBestCmap()
font.close()

# The cmap keys are int codepoints
return [chr(c) for c in cmap.keys()]


def LoadLanguages(languages_dir=None):
if languages_dir is None:
languages_dir = os.path.join(DATA_DIR, 'languages')
Expand Down Expand Up @@ -80,33 +65,3 @@ def LoadRegions(regions_dir=None):
region = text_format.Parse(f.read(), languages_public_pb2.RegionProto())
regions[region.id] = region
return regions


def SupportedLanguages(font_path, languages=None):
"""
Get languages supported by given font file.
Languages are pulled from the given set. Based on whether exemplar character
sets are present in the given font.
Logic based on Hyperglot:
https://github.com/rosettatype/hyperglot/blob/3172061ca05a62c0ff330eb802a17d4fad8b1a4d/lib/hyperglot/language.py#L273-L301
"""
if languages is None:
languages = LoadLanguages()

chars = _ParseFontChars(font_path)

supported = []
for lang in languages.values():
if not lang.HasField('exemplar_chars') or \
not lang.exemplar_chars.HasField('base'):
continue

base = hyperglot_parse.parse_chars(lang.exemplar_chars.base,
decompose=False,
retainDecomposed=False)
if set(base).issubset(chars):
supported.append(lang)

return supported
2 changes: 0 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
--index-url https://pypi.python.org/simple/
fontTools==4.29.1
hyperglot==0.3.7
protobuf==3.19.4
-e .
2 changes: 0 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@
python_requires=">=3.7",
setup_requires=['setuptools_scm>=4,<6.1'],
install_requires=[
'FontTools',
'hyperglot',
'protobuf',
'setuptools'
]
Expand Down
85 changes: 85 additions & 0 deletions snippets/supported_languages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
#
# Copyright 2022 The Google Fonts Tools Authors.
# Copyright 2017,2022 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# =======================================================================
# ======= This code-snippet uses hyperglot, which is licensed =======
# ======= under the GNU GPLv3. So, the resulting license for =======
# ======= any program using this snippet will also have to be =======
# ======= the GNU GPLv3. =======
# =======================================================================

from hyperglot import parse as hyperglot_parse


def _ParseFontChars(path):
"""
Open the provided font path and extract the codepoints encoded in the font
@return list of characters
"""
from fontTools.ttLib import TTFont
font = TTFont(path, lazy=True)
cmap = font["cmap"].getBestCmap()
font.close()

# The cmap keys are int codepoints
return [chr(c) for c in cmap.keys()]


def SupportedLanguages(font_path, languages=None):
"""
Get languages supported by given font file.
Languages are pulled from the given set. Based on whether exemplar character
sets are present in the given font.
Logic based on Hyperglot:
https://github.com/rosettatype/hyperglot/blob/3172061ca05a62c0ff330eb802a17d4fad8b1a4d/lib/hyperglot/language.py#L273-L301
"""
if languages is None:
languages = LoadLanguages()

chars = _ParseFontChars(font_path)

supported = []
for lang in languages.values():
if not lang.HasField('exemplar_chars') or \
not lang.exemplar_chars.HasField('base'):
continue

base = hyperglot_parse.parse_chars(lang.exemplar_chars.base,
decompose=False,
retainDecomposed=False)
if set(base).issubset(chars):
supported.append(lang)

return supported


def portable_path(p):
return os.path.join(*p.split('/'))


def TEST_FILE(f):
return portable_path("data/test/" + f)


def test_SupportedLanguages():
font = TEST_FILE('nunito/Nunito-Regular.ttf')
supported = SupportedLanguages(font)
langs = [supported[i].name for i, _ in enumerate(supported)]
assert len(langs) == 225
assert 'Lithuanian' in langs
16 changes: 0 additions & 16 deletions tests/test_gflanguages_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
from gflanguages import lang_support


def portable_path(p):
return os.path.join(*p.split('/'))


def TEST_FILE(f):
return portable_path("data/test/" + f)


def test_LoadLanguages():
langs = lang_support.LoadLanguages()
numerals = langs["yi_Hebr"].exemplar_chars.numerals
Expand All @@ -26,11 +18,3 @@ def test_LoadRegions():
br = regions["BR"]
assert br.name == 'Brazil'
assert br.region_group == ['Americas']


def test_SupportedLanguages():
font = TEST_FILE('nunito/Nunito-Regular.ttf')
supported = lang_support.SupportedLanguages(font)
langs = [supported[i].name for i, _ in enumerate(supported)]
assert len(langs) == 225
assert 'Lithuanian' in langs

0 comments on commit 3c8aa2e

Please sign in to comment.