Commit cb643a96 authored by Yao Wei (魏銘廷)'s avatar Yao Wei (魏銘廷)

New upstream version 0.8.6

parents
environment:
matrix:
- JOB: "2.7 32-bit"
PYTHON_HOME: "C:\\Python27"
TOXENV: "py27-cov"
TOXPYTHON: "C:\\Python27\\python.exe"
- JOB: "3.7 32-bit"
PYTHON_HOME: "C:\\Python37"
TOXENV: "py37-cov"
TOXPYTHON: "C:\\Python37\\python.exe"
- JOB: "2.7 64-bit"
PYTHON_HOME: "C:\\Python27-x64"
TOXENV: "py27-cov"
TOXPYTHON: "C:\\Python27-x64\\python.exe"
- JOB: "3.6 64-bit"
PYTHON_HOME: "C:\\Python36-x64"
TOXENV: "py36-cov"
TOXPYTHON: "C:\\Python36-x64\\python.exe"
- JOB: "3.7 64-bit"
PYTHON_HOME: "C:\\Python37-x64"
TOXENV: "py37-cov"
TOXPYTHON: "C:\\Python37-x64\\python.exe"
install:
# If there is a newer build queued for the same PR, cancel this one.
# The AppVeyor 'rollout builds' option is supposed to serve the same
# purpose but it is problematic because it tends to cancel builds pushed
# directly to master instead of just PR builds (or the converse).
# credits: JuliaLang developers.
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
# Prepend Python to the PATH of this build
- "SET PATH=%PYTHON_HOME%;%PYTHON_HOME%\\Scripts;%PATH%"
# check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
# upgrade pip and setuptools to avoid out-of-date warnings
- "python -m pip install --disable-pip-version-check --user --upgrade pip setuptools"
# install the dependencies to run the tests
- "python -m pip install tox"
build: false
test_script:
- "tox"
after_test:
- "tox -e codecov"
comment:
layout: "diff, files"
behavior: default
require_changes: true
coverage:
status:
project: off
patch: off
[run]
# measure 'branch' coverage in addition to 'statement' coverage
# See: http://coverage.readthedocs.io/en/coverage-4.5.1/branch.html
branch = True
# list of directories or packages to measure
source = fontParts
omit =
*/__init__.py
*/test/*
*/test.py
[paths]
source =
Lib/fontParts
.tox/*/lib/python*/site-packages/fontParts
.tox/pypy*/site-packages/fontParts
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# keywords to use in inline comments to skip coverage
pragma: no cover
# don't complain if tests don't hit defensive assertion code
(raise|except)(\s)?NotImplementedError
# don't complain if non-runnable code isn't run
if __name__ == .__main__.:
# ignore source code that can’t be found
ignore_errors = True
# when running a summary report, show missing lines
show_missing = True
.cache
.tox
.coverage
.coverage.*
.DS_Store
*.egg-info
__pycache__/
*.py[cod]
*.pyc
build/*
dist/*
.eggs/
.vscode
documentation/build/*
documentation/.sass-cache/*
documentation/source/_themes/fontPartsTheme/static/.sass-cache/*
doc/*
.pytest_cache
htmlcov
strictness: high
pylint:
run: false # since Codacy runs pylint in addition to prospector
pep8:
options:
single-line-if-stmt: n
disable:
- N802
sudo: false
language: python
python: 3.6
# empty "env:" is needed for 'allow_failures'
# https://docs.travis-ci.com/user/customizing-the-build/#Rows-that-are-Allowed-to-Fail
env:
matrix:
fast_finish: true
exclude:
- python: 3.6
include:
- python: 2.7
env: TOXENV=py27-cov
- python: 3.6
env:
- TOXENV=py36-cov
- BUILD_DIST=true
- python: 3.7
env: TOXENV=py37-cov
dist: xenial
sudo: true
- python: pypy
env: TOXENV=pypy-nocov
- language: generic
os: osx
env: TOXENV=py27-cov
- language: generic
os: osx
env:
- TOXENV=py3-cov
- HOMEBREW_NO_AUTO_UPDATE=1
- env:
- TOXENV=py27-nocov
- PYENV_VERSION='2.7.6'
- PYENV_VERSION_STRING='Python 2.7.6'
- PYENV_ROOT=$HOME/.travis-pyenv
- TRAVIS_PYENV_VERSION='0.4.0'
allow_failures:
# We use fast_finish + allow_failures because OSX builds take forever
# https://blog.travis-ci.com/2013-11-27-fast-finishing-builds
- language: generic
os: osx
env: TOXENV=py27-cov
- language: generic
os: osx
env:
- TOXENV=py3-cov
- HOMEBREW_NO_AUTO_UPDATE=1
cache:
- pip
- directories:
- $HOME/.pyenv_cache
before_install:
- source ./.travis/before_install.sh
install:
- ./.travis/install.sh
script:
- ./.travis/run.sh
after_success:
- ./.travis/after_success.sh
before_deploy:
- ./.travis/before_deploy.sh
deploy:
# deploy to Github Releases on tags
- provider: releases
api_key:
secure: pC8uLogIHAtrAbUr6cv493IGPIiC+RkVGQXR9z3HTisplrq+lzgoAo4ik5gzettfG4oVyt0ERGSxo61X7MIDv2idlGUgXJSHKQgf3IJPIsRU5jHJzo5YHpEy1bVygBesz3jFFKXGvr2nRQlwGr7+3dbHV+KJaszw91MnoNJkfRXKqQMJ8wDNpZm2O9SWfFO/hL9oouLfpNBUYKHZzRWTcSxR8rNe+vPW/ai7VAqbIkeXIBCqUl/kOWlK/M3aUnI9/3A8BuKXvXIKAgrpViR3HeTnymQc8CGVKjX2GlDQtI3XxcuMgoX69Y9azS+ajrh1YdlQNcqArLVhrsl404PFWPq9sV0jm0f1iUQhuhCrLZVjKEtYNbWj2HIaR42raT2mDR5u/a0LX89jTdWEoNkd+Qov7OA0djUd7Z2pmKvlbyCL8PwYlMStQ/jaQECp799JVu9/ky6tCDvE0ALFTzWCL0rUOYM9KPSb8mjSFW5ylmHBvQWc5rYtFtQn3fSFQwkj6r2x5Z99qszqHj7obLG8yLm19ddrx5JNVQSyTA+XgF2eUy0ilZRaAWTGb41U++RkHQpjkN6VFjanfi4hCB5gSWx7GDCV5DhSqId6z+XQPgS64xDWGfoS2v4Sa82mmQClv1HdQ23cyW48Ss3NctkDdwJSDsWZ10CFx7sI2ccAm+w=
skip_cleanup: true
file_glob: true
file: "dist/*"
on:
tags: true
repo: robotools/fontParts
all_branches: true
condition: "$BUILD_DIST == true"
# deploy to PyPI on tags
- provider: pypi
user: benkiel
password:
secure: "dQmUNMwDeq7162p3IE3M9d9BW3lfk/chaW8SY605YikW7J56bfT1CQFaOiYumdvMF/eWBrVxbQbdwdupL2sDm1dSgYKWu0ite1jePaoTkMhEKFr+XW7GogcX+LOiFa7FITscnWgV02XwijStbklQmZ2beBe/tjB5Ug/Swx6CVCsTN/j1n0+r3UjtHcsnVgN+XAhpC0+ewoyKkoKP/aalb2gGFwsRDh2SzJZ/sOICHmmjJUGDB6/vS8tGgnI1arDSpSH7KDNB1dVAfDvjK9yXFEDPkYO5vEU//vZWP9yKTqXPmDiv+SMg959UcdgCUnNPSv44/VDtqv9kNhG4t3Ye4bjV/WBnyZ3SiWF8XHI+r3nk6x6Swjhq8ZRPk861JhDPK67kCJHdmMjOfaKy+MoTWscDqLlzxxAABSv+HkgQ3LiHKqBbvJVBbuhbmFdo8qtmZXKl4z8LlUcTHskMAioEMbueKRW/+jEDN5xm0h7c4W2mfHyrnn3Td5hWpmXZKe7ZKqbU8koBruGJpnC6miE689nO6HLpQbW8AjYy6ZOkz4HbkZCAYh0NqYe7qwgFKx8+iYy5smWyiqAS7A4D1kyFzaXV5jEe87jddDc/wMofgcKSUBOGe9eM/w4FKVRCW8jAMkjMiZKVMzHE2f9nk9q4A8bU++Da/AgIw3JKOVnWAPg="
skip_cleanup: true
distributions: pass
on:
tags: true
repo: robotools/fontParts
all_branches: true
condition: "$BUILD_DIST == true"
#!/bin/bash
set -e
set -x
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
source .venv/bin/activate
fi
# upload coverage data to Codecov.io
[[ ${TOXENV} == *"-cov"* ]] && tox -e codecov
#!/bin/bash
set -e
set -x
# build sdist and wheel distribution packages in ./dist folder.
# Travis runs the `before_deploy` stage before each deployment, but
# we only want to build them once, as we want to use the same
# files for both Github and PyPI
if $(ls ./dist/fontParts*.zip > /dev/null 2>&1) && \
$(ls ./dist/fontParts*.whl > /dev/null 2>&1); then
echo "Distribution packages already exists; skipping"
else
tox -e bdist
fi
#!/bin/bash
if [[ -n "$PYENV_VERSION" ]]; then
wget https://github.com/praekeltfoundation/travis-pyenv/releases/download/${TRAVIS_PYENV_VERSION}/setup-pyenv.sh
source setup-pyenv.sh
fi
#!/bin/bash
set -e
set -x
ci_requirements="pip setuptools tox"
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
if [[ ${TOXENV} == *"py27"* ]]; then
# install pip on the system python
curl -O https://bootstrap.pypa.io/get-pip.py
python get-pip.py --user
# install virtualenv and create virtual environment
python -m pip install --user virtualenv
python -m virtualenv .venv/
elif [[ ${TOXENV} == *"py3"* ]]; then
# install current python3 with homebrew
# NOTE: the formula is now named just "python"
brew install python
command -v python3
python3 --version
python3 -m pip install virtualenv
python3 -m virtualenv .venv/
else
echo "unsupported $TOXENV: "${TOXENV}
exit 1
fi
# activate virtual environment
source .venv/bin/activate
fi
python -m pip install $ci_requirements
#!/bin/bash
set -e
set -x
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
source .venv/bin/activate
fi
tox
This diff is collapsed.
The MIT License (MIT)
Copyright (c) 2016 The RoboFab Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
__version__ = "0.8.6"
from fontParts.base.errors import FontPartsError
from fontParts.base.font import BaseFont
from fontParts.base.info import BaseInfo
from fontParts.base.groups import BaseGroups
from fontParts.base.kerning import BaseKerning
from fontParts.base.features import BaseFeatures
from fontParts.base.lib import BaseLib
from fontParts.base.layer import BaseLayer
from fontParts.base.glyph import BaseGlyph
from fontParts.base.contour import BaseContour
from fontParts.base.point import BasePoint
from fontParts.base.segment import BaseSegment
from fontParts.base.bPoint import BaseBPoint
from fontParts.base.component import BaseComponent
from fontParts.base.anchor import BaseAnchor
from fontParts.base.guideline import BaseGuideline
from fontParts.base.image import BaseImage
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
class Color(tuple):
"""
An color object. This follows the :ref:`type-color`.
"""
def _get_r(self):
return self[0]
r = property(_get_r,
"The color's red component as :ref:`type-int-float`.")
def _get_g(self):
return self[1]
g = property(_get_g,
"The color's green component as :ref:`type-int-float`.")
def _get_b(self):
return self[2]
b = property(_get_b,
"The color's blue component as :ref:`type-int-float`.")
def _get_a(self):
return self[3]
a = property(_get_a,
"The color's alpha component as :ref:`type-int-float`.")
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# -------------------
# Universal Exception
# -------------------
class FontPartsError(Exception):
pass
from fontParts.base.base import BaseObject, dynamicProperty, reference
from fontParts.base import normalizers
from fontParts.base.deprecated import DeprecatedFeatures, RemovedFeatures
class BaseFeatures(BaseObject, DeprecatedFeatures, RemovedFeatures):
copyAttributes = ("text",)
def _reprContents(self):
contents = []
if self.font is not None:
contents.append("for font")
contents += self.font._reprContents()
return contents
# -------
# Parents
# -------
# Font
_font = None
font = dynamicProperty("font", "The features' parent :class:`BaseFont`.")
def _get_font(self):
if self._font is None:
return None
return self._font()
def _set_font(self, font):
if self._font is not None and self._font() != font:
raise AssertionError("font for features already set and is not same as font")
if font is not None:
font = reference(font)
self._font = font
# ----
# Text
# ----
text = dynamicProperty(
"base_text",
"""
The `.fea formated
<http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html>`_
text representing the features.
It must be a :ref:`type-string`.
"""
)
def _get_base_text(self):
value = self._get_text()
if value is not None:
value = normalizers.normalizeFeatureText(value)
return value
def _set_base_text(self, value):
if value is not None:
value = normalizers.normalizeFeatureText(value)
self._set_text(value)
def _get_text(self):
"""
This is the environment implementation of
:attr:`BaseFeatures.text`. This must return a
:ref:`type-string`.
Subclasses must override this method.
"""
self.raiseNotImplementedError()
def _set_text(self, value):
"""
This is the environment implementation of
:attr:`BaseFeatures.text`. **value** will be
a :ref:`type-string`.
Subclasses must override this method.
"""
self.raiseNotImplementedError()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
from fontParts.base.errors import FontPartsError
from fontParts.fontshell.font import RFont
from fontParts.fontshell.info import RInfo
from fontParts.fontshell.groups import RGroups
from fontParts.fontshell.kerning import RKerning
from fontParts.fontshell.features import RFeatures
from fontParts.fontshell.lib import RLib
from fontParts.fontshell.layer import RLayer
from fontParts.fontshell.glyph import RGlyph
from fontParts.fontshell.contour import RContour
from fontParts.fontshell.point import RPoint
from fontParts.fontshell.segment import RSegment
from fontParts.fontshell.bPoint import RBPoint
from fontParts.fontshell.component import RComponent
from fontParts.fontshell.anchor import RAnchor
from fontParts.fontshell.guideline import RGuideline
from fontParts.fontshell.image import RImage
import defcon
from fontParts.base import BaseAnchor
from fontParts.fontshell.base import RBaseObject
class RAnchor(RBaseObject, BaseAnchor):
wrapClass = defcon.Anchor
def _init(self, wrap=None):
if wrap is None:
wrap = self.wrapClass()
wrap.x = 0
wrap.y = 0
super(RAnchor, self)._init(wrap=wrap)
# --------
# Position
# --------
# x
def _get_x(self):
return self.naked().x
def _set_x(self, value):
self.naked().x = value
# y
def _get_y(self):
return self.naked().y
def _set_y(self, value):
self.naked().y = value
# --------------
# Identification
# --------------
# identifier
def _get_identifier(self):
anchor = self.naked()
return anchor.identifier
def _getIdentifier(self):
anchor = self.naked()
return anchor.generateIdentifier()
def _setIdentifier(self, value):
self.naked().identifier = value
# name
def _get_name(self):
return self.naked().name
def _set_name(self, value):
self.naked().name = value
# color
def _get_color(self):
value = self.naked().color
if value is not None:
value = tuple(value)
return value
def _set_color(self, value):
self.naked().color = value
from fontParts.base import BaseBPoint
from fontParts.fontshell.base import RBaseObject
class RBPoint(BaseBPoint, RBaseObject):
pass
class RBaseObject(object):
wrapClass = None
def _init(self, wrap=None):
if wrap is None and self.wrapClass is not None:
wrap = self.wrapClass()
if wrap is not None:
self._wrapped = wrap
def naked(self):
if hasattr(self, "_wrapped"):
return self._wrapped
return None
import defcon
from fontParts.base import BaseComponent
from fontParts.fontshell.base import RBaseObject
class RComponent(RBaseObject, BaseComponent):
wrapClass = defcon.Component
# ----------
# Attributes
# ----------
# baseGlyph
def _get_baseGlyph(self):
return self.naked().baseGlyph
def _set_baseGlyph(self, value):
self.naked().baseGlyph = value
# transformation
def _get_transformation(self):
return self.naked().transformation
def _set_transformation(self, value):
self.naked().transformation = value
# --------------
# Identification
# --------------
# index
def _set_index(self, value):
component = self.naked()
glyph = component.glyph
if value > glyph.components.index(component):
value -= 1
glyph.removeComponent(component)
glyph.insertComponent(value, component)