This document presents information that will help font developers create or support OpenType fonts for all Arabic script languages covered by the Unicode Standard.
Introduction
Font developers will learn how to encode complex script features in their fonts, choose character sets, organize font information, and use existing tools to produce Arabic fonts. Registered features of the Arabic script are defined and illustrated, encodings are listed, and templates are included for compiling Arabic layout tables for OpenType fonts.
This document also presents information about the Arabic OpenType shaping engine of Uniscribe, the Windows component responsible for text layout.
In addition to being a primer and specification for the creation and support of Arabic fonts, this document is intended to more broadly illustrate the OpenType Layout architecture, feature schemes, and operating system support for shaping and positioning text.
Glossary
The following terms are useful for understanding the layout features and script rules discussed in this document.
Base Glyph - Any glyph that can have a diacritic mark above or below it. Layout operations are defined in terms of a base glyph, not a base character, as a ligature may act as the base.
Character - Each character represents a Unicode character code point. For example 'lam' character is U+0644. A character may have multiple forms of glyphs.
Diacritic Marks - A character that is positioned above or below a character to provide pronunciation guidance (i.e. accent acute, grave, tilde, etc.)
Glyph - A glyph represents a form of one or more characters. For example, the final, initial and medial 'lam' glyphs (U+FEDE, U+FEDF & U+FEE0) are all forms of the 'lam' character (U+0644).
Kashida - Also known as the 'tatweel' character (U+0640). This character is used for elongation between connecting characters and is used for justification.
Ligature - A combination of glyphs that join to form a single glyph. For example, the 'lam alef' combinations of glyphs are mandatory ligatures for Arabic. Other ligatures, like 'lam meem initial', are optional.
The Uniscribe Arabic shaping engine processes text in stages. The stages are:
- Analyzing the characters for contextual shape
- Shaping (substituting) glyphs with OTLS (OpenType Library Services)
- Positioning glyphs with OTLS
The descriptions which follow will help font developers understand the rationale for the Arabic feature encoding model, and help application developers better understand how layout clients can divide responsibilities with operating system functions.
Analyzing the Characters
The unit that the shaping engine receives for the purpose of shaping is a string of Unicode characters, in a sequence. The contextual analysis engine determines the correct contextual form the character should take, based on the character before and after it. The contextual shape maps to an OTL feature for that form (isol, init, medi, fina).
Additionally, during the analysis process, the engine verifies valid diacritic combinations. For additional information, see the Handling Invalid Combining Marks section.
Shaping with OTLS
The first step Uniscribe takes in shaping the character string is to map all characters to their nominal form glyphs (e.g. the glyph for U+0627). Then, Uniscribe applies contextual shape features to the glyph string.
Next, Uniscribe calls OTLS to apply the features. All OTL processing is divided into a set of predefined features (described and illustrated in the Features section of this document). Each feature is applied, one by one, to the appropriate glyphs in the syllable and OTLS processes them. Uniscribe makes as many calls to the OTL Services as there are features. This ensures that the features are executed in the desired order.
The steps of the shaping process are outlined below. Not all of the features listed apply to all Arabic script languages.
Shaping features:
- Language forms
- Apply feature 'ccmp' to preprocess any glyphs that require composition or decomposition (for example, 'alef' followed by 'hamza above' may be composed into 'alef with hamza above')
- Apply feature 'isol' to get the isolated form of characters
- Apply feature 'fina' to get final form glyphs
- Apply feature 'medi' to get medial form glyphs
- Apply feature 'init' to get initial form glyphs
- Apply feature 'rlig' to compose any mandatory ligatures, like 'lam alef'
- Apply feature 'calt' to apply any desired alternative forms of connections; this can provide type designers with the capability to contextually exchange a glyph to give a better calligraphic presentation
- Typographical forms
- Apply feature 'liga' to compose any optional ligatures, like 'lam meem'
- Apply feature 'dlig' to compose any discretionary ligatures
- Apply feature 'cswh' to substitute any swash characters based on context; for example, a swash 'noon' might be used if followed by n glyphs that do not extend below the baseline
- Apply feature 'mset' to apply mark positioning via substitution; this does not produce the best typographic possibilities as would the use of the positioning feature 'mark'
Positioning Glyphs with OTLS
Uniscribe next applies features concerned with positioning, calling functions of OTLS to position glyphs.
Positioning features:
- Cursive connection
- Apply feature 'curs' to connect cursive font glyphs as appropriate
- Kerning
- Apply feature 'kern' to provide pair kerning between base glyphs requiring adjustment for better typographical quality
- Mark to base
- Apply feature 'mark' to position diacritic glyphs to the base glyph
- Mark to Mark
- Apply feature 'mkmk' to position diacritic glyphs to other diacritic glyphs
Handling Invalid Combining Marks
Combining marks and signs that appear in text not in conjunction with a valid consonant base are considered invalid. Uniscribe displays these marks using the fallback rendering mechanism defined in the Unicode Standard (section 5.12, 'Rendering Non-Spacing Marks' of the Unicode Standard 3.1), i.e. positioned on a dotted circle.
Please note that to render a sign standalone (in apparent isolation from any base) one should apply it on a space (see section 2.5 'Combining Marks' of Unicode Standard 3.1). Uniscribe requires a ZWJ to be placed between the space and a mark for them to combine into a standalone sign.
For the fallback mechanism to work properly, an Arabic OTL font should contain a glyph for the dotted circle (U+25CC). In case this glyph is missing form the font, the invalid signs will be displayed on the missing glyph shape (white box).
In addition to the 'dotted circle,' other Unicode code points that are recommended for inclusion in any Arabic font are: ZWNJ (zero width non-joiner; U+200C), ZWJ (zero width joiner U+200D), LTR (left to right mark; U+200E), and RTL (right to left mark; U+200F). The ZWNJ can be used between two letters to prevent them from forming a cursive connection.
If an invalid combination is found, like two fathas on the same base character, the diacritic that causes the invalid state is placed on a dotted circle to indicate to the user the invalid combination. The shaping engine for non-OpenType fonts will cause invalid mark combinations to overstrike. This is the problem that inserting the dotted circle for the invalid base solves. It should also be noted that the dotted circle is not inserted into the application's backing store. This is a run-time insertion into the glyph array that is returned from the ScriptShape function.
The invalid diacritic logic for Arabic is based on the classes listed below. There is a check to make sure more than one mark of a class is not placed on the same base. Additionally, DIAC1 and DIAC2 classes should not be applied on the same base character.
Class | Description | Code points |
---|---|---|
DIAC1 | Arabic above diacritics | U+064B, U+064C, U+064E, U+064F, U+0652, U+0657, U+0658, U+06E1 |
DIAC2 | Arabic below diacritics | U+064D, U+0650, U+0656 |
DIAC3 | Arabic seat shadda | U+0651 |
DIAC4 | Arabic Qur'anic marks above | U+0610 - U+0614, U+0659, U+06D6 - U+06DC, U+06DF, U+06E0, U+06E2, U+06E4, U+06E7, U+06E8, U+06EB, U+06EC |
DIAC5 | Arabic Qur'anic marks below | U+06E3, U+06EA, U+06ED |
DIAC6 | Arabic superscript alef | U+0670 |
DIAC7 | Arabic madda | U+0653 |
DIAC8 | Arabic madda | U+0654, U+0655 |
The features listed below have been defined to create the basic forms for the languages that are supported on Arabic systems. Regardless of the model an application chooses for supporting layout of complex scripts, Uniscribe requires a fixed order for executing features within a run of text to consistently obtain the proper basic form. This is achieved by calling features one-by-one in the standard order listed below.
The order of the lookups within each feature is also very important. For more information on lookups and defining features in OpenType fonts, see the Encoding section of the OpenType Font Development document.
The standard order for applying Arabic features encoded in OpenType fonts:
Not all of the features listed below apply to all Arabic script languages.
Feature | Feature function | Layout operation | Always applied | On by default | Off by default |
---|---|---|---|---|---|
Language based forms: | |||||
ccmp | Character composition/decomposition substitution | GSUB | X | ||
isol | Isolated character form substitution | GSUB | X | ||
fina | Final character form substitution | GSUB | X | ||
medi | Medial character form substitution | GSUB | X | ||
init | Initial character form substitution | GSUB | X | ||
rlig | Required ligature substitution | GSUB | X | ||
rclt | Required contextual alternates substitution | GSUB | X | ||
calt | Contextual alternates substitution | GSUB | X | ||
Typographical forms: | |||||
liga | Standard ligature substitution | GSUB | X | ||
dlig | Discretionary ligature substitution | GSUB | X | ||
cswh | Contextual swashes | GSUB | X | ||
mset | Mark positioning via substitution | GSUB | X | ||
Positioning features: | |||||
curs | Cursive positioning | GPOS | X | ||
kern | Pair kerning | GPOS | X | ||
mark | Mark to base positioning | GPOS | X | ||
mkmk | Mark to mark positioning | GPOS | X | ||
[GSUB = glyph substitution, GPOS = glyph positioning] |
Descriptions and examples of above features
Many of the registered features described and illustrated in this document are based on the OpenType font Arabic Typesetting. Arabic Typesetting contains layout information and glyphs to support all of the required features for the Arabic script and language systems supported. The Arabic Typesetting font will be available as part of Visual OpenType Layout Tool (VOLT) and is provided under the terms of the VOLT supplemental files end user license agreement. The Arabic Typesetting font is available for download in the Appendix of this document
Character composition (and decomposition)
Feature Tag: 'ccmp'
The 'ccmp' feature is used to compose a number of glyphs into one glyph, or decompose one glyph into a number of glyphs. This feature is implemented before any other features because there may be times when a font vender wants to control certain shaping of glyphs. An example of using this table is seen below. Varuthapadatha valibar sangam full movie download mp4. The 'ccmp' table maps default alphabetic forms to both a composed form (essentially a ligature, GSUB lookup type 4), and decomposed forms (GSUB lookup type 2).
The rationale for the decomposition illustrated above is to take advantage of the color diacritic feature found in Microsoft applications like Word and Publisher.
![Font Ttf Low Unicode By Kiva Font Ttf Low Unicode By Kiva](https://fedoramagazine.org/wp-content/uploads/2015/02/monospace-945x400.png)
Isolated form
Feature Tag: 'isol'
The 'isol' feature is used to map the Unicode character value to its isolated form. This is usually the same glyph form. However, Unicode defines Arabic presentation forms as different than the Unicode character form. If a vender has a good quality font tool, or a font utility that can edit the CMAP table, more than one Unicode character can point to the same glyph ID. (GSUB lookup type 1).
Final form
Feature Tag: 'fina'
The 'fina' feature is used to map the Unicode character value to its final form. (GSUB lookup type 1).
Medial form
List Of Unicode Fonts
Feature Tag: 'medi'
The 'medi' feature is used to map the Unicode character value to its medial form. (GSUB lookup type 1).
Initial form
Feature Tag: 'init'
The 'init' feature is used to map the Unicode character value to its initial form. (GSUB lookup type 1).
Required ligatures
Feature Tag: 'rlig'
The 'rlig' feature is used to map glyph values to their correct ligated form. Font developers should use this table for all ligatures that they want to map as such all of the time. Ligatures that should be optional, based on user preferences should not be included in this table. Optional ligatures are defined in the 'liga' table.
The 'rlig' feature maps sequences of glyphs to corresponding ligatures (GSUB lookup type 4). Ligatures with more components must be stored ahead of those with fewer components in order to be found. See Ordering ligatures in the Encoding section of the OpenType Font Development document. The set of required ligatures will vary by design and script.
NOTE: If you want your fonts to have some level of backward compatibility with Windows9x/ME system level support you will also want to include the items in the 'rlig' feature in the 'liga' feature. This is because older operating systems do not use Uniscribe for shaping and are not aware of the 'rlig' feature.
Connection forms
Feature Tag: 'rclt' or 'calt'
![Font Font](https://linux-cdn.softpedia.com/screenshots/Character-Map_1.png)
In specified situations, replaces default glyphs with alternate forms that provide better joining behavior. Used in script typefaces which are designed to have some or all of their glyphs join. The 'calt' feature specifies the context in which each substitution occurs, and maps one or more default glyphs to replacement glyphs (GSUB lookup type 6). Substitutions that are required for script correctness should be put under 'rclt'.”
NOTE: If you want your fonts to have some level of backward compatibility with Windows7/8.1 system level support you will also want to include the items in the 'rclt' feature in the 'calt' feature. This is because older operating systems are not aware of the 'rclt' feature. The 'calt' is always applied for Arabic to preserve documents using older fonts.
The 'calt' feature specifies the context in which each substitution occurs, and maps one or more default glyphs to replacement glyphs (GSUB lookup type 6). Substitutions that are required for script correctness should be put under 'rclt'.
Standard ligatures
Feature Tag: 'liga'
The 'liga' feature is used to map glyphs to their optional ligated form. Font developers should use this table for all ligatures that should be on by default but may be turned off by user preference. Uniscribe applies this feature by default but will allow this feature to be deactivated. Non-required features, including ‘liga’, can be disabled by passing in a custom font feature list that specifies a feature as off for the entire run. The 'liga' feature maps sequences of glyphs to corresponding ligatures (GSUB lookup type 4). Ligatures with more components must be stored ahead of those with fewer components in order to be found. See Ordering ligatures in the Encoding section of the OpenType Font Development document. The set of optional ligatures will vary by typeface design and script.
NOTE: Ligatures that should be formed all of the time should not be included in this feature type. Required ligatures are defined in the 'rlig' table.
Discretionary ligatures
Feature Tag: 'dlig'
The 'dlig' feature is used to map glyphs to their optional ligated form. Font developers should use this table for all ligatures that should be off by default but may be turned on by user preference. Optional features, including ‘dlig’, can be enabled by passing in a custom font feature list that specifies an optional feature as on for the entire run. The 'dlig' feature maps sequences of glyphs to corresponding ligatures (GSUB lookup type 4). Ligatures with more components must be stored ahead of those with fewer components in order to be found. See Ordering ligatures in the Encoding section of the OpenType Font Development document. The set of optional ligatures will vary by typeface design and script.
Contextual swash
Feature Tag: 'cswh'
The 'cswh' feature replaces default character glyphs with corresponding swash glyphs based upon the context surrounding the character. Note that there may be more than one swash alternate for a given character. The 'cswh' table maps glyph IDs for default forms to those for one or more corresponding swash forms. While many of these substitutions are one-to-one (GSUB lookup type 1), others require a selection from a set (GSUB lookup type 3). Font developers may choose to build two tables (one for each lookup type) or only one that uses lookup type 3 for all substitutions. If several styles of swash are present across the font, the set of forms for each character should be ordered consistently
The 'cswh' feature is off by default but may be turned on by user preference. Optional features, including ‘cswh’, can be enabled by passing in a custom font feature list that specifies an optional feature as on for the entire run.
Mark positioning via substitution
Feature Tag: 'mset'
The 'mset' feature is used to position Arabic combining marks in fonts for Windows 95 using glyph substitution. In Arabic, the Hamza is positioned differently when placed above a Yeh Barree as compared to the Alef. Windows 95 implementation: In contrast to the 'mark' feature, the 'mset' feature uses glyph substitution to combine marks and base glyphs. It replaces a default mark glyph with a correctly positioned mark glyph. The font designer specifies the position of the mark when describing the mark's contour in the font file. Microsoft's Arabic fonts, created for Windows 95, use a contextual substitution lookup (GSUB LookupType = 5) to implement the 'mset' feature.
Example: the default fatha is positioned high and the 'mset' feature is used to substitute a low form when placed over a Beh.
Cursive positioning
Feature Tag: 'curs'
The 'curs' feature positions cursive characters so that the exit point of the current character matches with entry point of the following character. The 'curs' table maps connecting point of joining glyphs and may be implemented as a Cursive Attachment (GPOS lookup type 3).
Kerning
Feature Tag: 'kern'
The 'kern' feature is used to adjust amount of space between glyphs, generally to provide optically consistent spacing between glyphs. Although a well-designed typeface has consistent inter-glyph spacing overall, some glyph combinations require adjustment for improved legibility. Besides standard adjustment in either horizontal or vertical direction, this feature can supply size-dependent kerning data via device tables, 'cross-stream' kerning in the Y text direction, and adjustment of glyph placement independent of the advance adjustment. Note that this feature would not be used in monospaced fonts.
The font stores a set of adjustments for pairs of glyphs (GPOS lookup type 2 or 8). These may be stored as one or more tables matching left and right classes, and/or as individual pairs. If both forms are used, the classes should be listed last, so as to provide a means to replace any non-ideal values that may result from the class tables. Additional adjustments may be provided for larger sets of glyphs (e.g., triplets, quadruplets, etc.) to overwrite the results of pair kerns in particular combinations. These should precede the pairs.
Creating kern table using Microsoft VOLT
Mark to base positioning
Feature Tag: 'mark'
The 'mark' feature positions mark glyphs in relation to a base glyph, or a ligature glyph. This feature may be implemented as a MarkToBase Attachment lookup (GPOS LookupType = 4) or a MarkToLigature Attachment lookup (GPOS LookupType = 5).
Positioning mark to base using Microsoft VOLT
Positioning mark to base (ligature) using Microsoft VOLT
Mark to mark positioning
Feature Tag: 'mkmk'
The 'mkmk' feature positions mark glyphs in relation to another mark glyph. This feature may be implemented as a MarkToMark Attachment lookup (GPOS LookupType = 6).
Positioning mark to mark using Microsoft VOLT
Appendix A: Writing System Tags
Features are encoded according to both a designated script and language system. The language system tag specifies a typographic convention associated with a language or linguistic subgroup. For example, there are different language systems defined for the Arabic script; Arabic, Baluchi, Ladakhi, Pashto, etc. Other typographic systems could be defined for Moroccan Arabic or Wahabi tradition of Qur'anic typography.
Outlook pst repair tool download. Currently, the Uniscribe engine only supports the 'default' language for each script. However, font developers may want to build language specific features which are supported in other applications and will be supported in future Microsoft OpenType implementations.
- NOTE: It is strongly recommended to include the 'dflt' language tag in all OpenType fonts because it defines the basic script handling for a font. The 'dflt' language system is used as the default if no other language specific features are defined or if the application does not support that particular language. If the 'dflt' tag is not present for the script being used, the font may not work in some applications.
The following tables list the registered tag names for scripts and language systems.
Registered tags for the Arabic script | Registered tags for Arabic language systems | ||
---|---|---|---|
Script tag | Script | Language system tag | Language |
'arab' | Arabic | 'dflt' | *default script handling |
'ARA ' | Arabic | ||
'BLI ' | Baluchi | ||
'BLT ' | Balti | ||
'BBR ' | Berber | ||
'BRH ' | Brahui | ||
'FAR ' | Persian | ||
'FUL ' | Fulah | ||
'HAU ' | Hausa | ||
'HND ' | Hindko | ||
'KNR ' | Kanuri | ||
'KSH ' | Kashmiri | ||
'KHW ' | Khowar | ||
'KUR ' | Kurdish | ||
'LDK ' | Ladakhi | ||
'MLY ' | Malay | ||
'MND ' | Mandinka | ||
'PAS ' | Pashto | ||
'PAN ' | Punjabi | ||
'SRK ' | Saraiki | ||
'SND ' | Sindhi | ||
'SML ' | Somali | ||
'SWK ' | Swahili | ||
'URD ' | Urdu | ||
'UYG ' | Uyghur |
NOTE: both the script and language tags are case sensitive (script tags should be lowercase, language tags are all caps) and must contain four characters (i.e. you must add a space to the three character language tags).
Appendix B: ARABTYPE.TTF (sample font)
The Arabic Typesetting font will be distributed with Microsoft Visual OpenType Layout Tool (VOLT) and is provided under the terms of the VOLT supplemental files end user license agreement. It is provided for illustration only, and may not be altered or redistributed.
Arabic Typesetting supports all characters from the Unicode Arabic and Arabic Extended blocks. As such, it can be used to produce documents in Arabic, Farsi, Urdu, Sindhi, Malay, and Uighur. The font is the Arabic naskh style of calligraphy.
Arabic Typesetting contains layout information and glyphs to support all of the required features for the languages supported. The font contains over 1600 Arabic glyphs. It is not necessary for all fonts to support this many glyphs or ligatures. Each font should be designed as the font creator desires.
Many shaped glyph forms (such as ligatures) have no Unicode encoding. These glyphs have id's in the font, and applications can access these glyphs by 'running' the layout features which depend on these glyphs. An application can also identify non-Unicode glyphs contained in the font by traversing the OpenType layout tables, or using the layout services for purely informational purposes.
Arabic Typesetting contains three OpenType Layout tables: GSUB (glyph substitution), GPOS (glyph positioning), and GDEF (glyph definition, distinguishing base glyphs, ligatures, classes of mark glyphs, etc.).
Go to the VOLT community Web site to download this sample font. Please be sure to read the end user license agreement that accompanies the download.
PermalinkJoin GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upBranch:master
'' |
####### NOTE ####### |
This is based heavily on matplotlib's font_manager.py rev 8713, |
but has been modified to not use other matplotlib modules |
#################### |
A module for finding, managing, and using fonts across platforms. |
This module provides a single :class:`FontManager` instance that can |
be shared across backends and platforms. The :func:`findfont` |
function returns the best TrueType (TTF) font file in the local or |
system font path that matches the specified :class:`FontProperties` |
instance. The :class:`FontManager` also handles Adobe Font Metrics |
(AFM) font files for use by the PostScript backend. |
The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1) |
font specification <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_. |
Future versions may implement the Level 2 or 2.1 specifications. |
Experimental support is included for using `fontconfig` on Unix |
variant platforms (Linux, OS X, Solaris). To enable it, set the |
constant ``USE_FONTCONFIG`` in this file to ``True``. Fontconfig has |
the advantage that it is the standard way to look up fonts on X11 |
platforms, so if a font is installed, it is much more likely to be |
found. |
KNOWN ISSUES |
- documentation |
- font variant is untested |
- font stretch is incomplete |
- font size is incomplete |
- font size_adjust is incomplete |
- default font algorithm needs improvement and testing |
- setWeights function needs improvement |
- 'light' is an invalid weight value, remove it. |
- update_fonts not implemented |
Authors : John Hunter <[email protected]> |
Paul Barrett <[email protected]> |
Michael Droettboom <[email protected]> |
Copyright : John Hunter (2004,2005), Paul Barrett (2004,2005) |
License : matplotlib license (PSF compatible) |
The font directory code is from ttfquery, |
see license/LICENSE_TTFQUERY. |
'' |
from__future__import absolute_import, print_function |
import logging |
import os |
import sys |
import glob |
import subprocess |
import warnings |
import tempfile |
import errno |
import six |
import six.moves as sm |
from fontTools.ttLib import TTCollection, TTFont, TTLibError |
from traits.etsconfig.api import ETSConfig |
from . import afm |
logger = logging.getLogger(__name__) |
USE_FONTCONFIG=False |
font_scalings = { |
'xx-small': 0.579, |
'x-small': 0.694, |
'small': 0.833, |
'medium': 1.0, |
'large': 1.200, |
'x-large': 1.440, |
'xx-large': 1.728, |
'larger': 1.2, |
'smaller': 0.833, |
None: 1.0 |
} |
stretch_dict = { |
'ultra-condensed': 100, |
'extra-condensed': 200, |
'condensed': 300, |
'semi-condensed': 400, |
'normal': 500, |
'semi-expanded': 600, |
'expanded': 700, |
'extra-expanded': 800, |
'ultra-expanded': 900 |
} |
weight_dict = { |
'ultralight': 100, |
'light': 200, |
'normal': 400, |
'regular': 400, |
'book': 400, |
'medium': 500, |
'roman': 500, |
'semibold': 600, |
'demibold': 600, |
'demi': 600, |
'bold': 700, |
'heavy': 800, |
'extra bold': 800, |
'black': 900 |
} |
font_family_aliases =set(['serif', 'sans-serif', 'sans serif', 'cursive', |
'fantasy', 'monospace', 'sans', 'modern']) |
# OS Font paths |
MSFolders = |
r'SoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders' |
MSFontDirectories = [ |
r'SOFTWAREMicrosoftWindows NTCurrentVersionFonts', |
r'SOFTWAREMicrosoftWindowsCurrentVersionFonts' |
] |
X11FontDirectories = [ |
# an old standard installation point |
'/usr/X11R6/lib/X11/fonts/TTF/', |
# here is the new standard location for fonts |
'/usr/share/fonts/', |
# documented as a good place to install new fonts |
'/usr/local/share/fonts/', |
# common application, not really useful |
'/usr/lib/openoffice/share/fonts/truetype/', |
] |
OSXFontDirectories = [ |
'/Library/Fonts/', |
'/Network/Library/Fonts/', |
'/System/Library/Fonts/' |
] |
ifnotUSE_FONTCONFIG: |
home = os.environ.get('HOME') |
if home isnotNone: |
# user fonts on OSX |
path = os.path.join(home, 'Library', 'Fonts') |
OSXFontDirectories.append(path) |
path = os.path.join(home, '.fonts') |
X11FontDirectories.append(path) |
############################################################################### |
# functions to replace those that matplotlib ship in different modules |
############################################################################### |
preferred_fonts = { |
'fantasy': ['Comic Sans MS', 'Chicago', 'Charcoal', 'ImpactWestern', |
'fantasy'], |
'cursive': ['Apple Chancery', 'Textile', 'Zapf Chancery', 'Sand', |
'cursive'], |
'monospace': ['Bitstream Vera Sans Mono', 'DejaVu Sans Mono', |
'Andale Mono', 'Nimbus Mono L', 'Courier New', 'Courier', |
'Fixed', 'Terminal', 'monospace'], |
'serif': ['Bitstream Vera Serif', 'DejaVu Serif', 'New Century Schoolbook', |
'Century Schoolbook L', 'Utopia', 'ITC Bookman', 'Bookman', |
'Nimbus Roman No9 L', 'Times New Roman', 'Times', 'Palatino', |
'Charter', 'serif'], |
'sans-serif': ['Bitstream Vera Sans', 'DejaVu Sans', 'Lucida Grande', |
'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', |
'Avant Garde', 'sans-serif'] |
} |
def_is_writable_dir(p): |
'' |
p is a string pointing to a putative writable dir -- return True p |
is such a string, else False |
'' |
ifnotisinstance(p, six.string_types): |
returnFalse |
try: |
t = tempfile.TemporaryFile(dir=p) |
t.write(b'kiva.test') |
t.close() |
exceptOSError: |
returnFalse |
else: |
returnTrue |
defget_configdir(): |
'' |
Return the string representing the configuration dir. If s is the |
special string _default_, use HOME/.kiva. s must be writable |
'' |
p = os.path.join(ETSConfig.application_data, 'kiva') |
try: |
os.makedirs(p) |
exceptOSErroras e: |
if e.errno != errno.EEXIST: |
raise |
ifnot _is_writable_dir(p): |
raiseIOError('Configuration directory %s must be writable'% p) |
return p |
defis_string_like(obj): |
'Return True if *obj* looks like a string' |
from numpy import ma |
ifisinstance(obj, six.string_types): |
returnTrue |
# numpy strings are subclass of str, ma strings are not |
if ma.isMaskedArray(obj): |
if obj.ndim 0and obj.dtype.kind in'SU': |
returnTrue |
else: |
returnFalse |
try: |
obj +'' |
except: |
returnFalse |
returnTrue |
defgetPropDict(font): |
n = font['name'] |
propdict = {} |
for prop in n.names: |
prop_key = (prop.platformID, prop.platEncID, prop.langID, prop.nameID) |
propdict[prop_key] = prop.string |
return propdict |
############################################################################### |
# matplotlib code below |
############################################################################### |
synonyms = {'ttf': ('ttf', 'otf', 'ttc'), |
'otf': ('ttf', 'otf', 'ttc'), |
'ttc': ('ttf', 'otf', 'ttc'), |
'afm': ('afm',)} |
defget_fontext_synonyms(fontext): |
'' |
Return a list of file extensions extensions that are synonyms for |
the given file extension *fileext*. |
'' |
return synonyms[fontext] |
defwin32FontDirectory(): |
'' |
Return the user-specified font directory for Win32. This is |
looked up from the registry key:: |
HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerShell FoldersFonts # noqa |
If the key is not found, $WINDIR/Fonts will be returned. |
'' |
try: |
from six.moves import winreg |
exceptImportError: |
pass# Fall through to default |
else: |
try: |
user = winreg.OpenKey(winreg.HKEY_CURRENT_USER, MSFolders) |
try: |
try: |
return winreg.QueryValueEx(user, 'Fonts')[0] |
exceptOSError: |
pass# Fall through to default |
finally: |
winreg.CloseKey(user) |
exceptOSError: |
pass# Fall through to default |
return os.path.join(os.environ['WINDIR'], 'Fonts') |
defwin32InstalledFonts(directory=None, fontext='ttf'): |
'' |
Search for fonts in the specified font directory, or use the |
system directories if none given. A list of TrueType font |
filenames are returned by default, or AFM fonts if *fontext* |
'afm'. |
'' |
from six.moves import winreg |
if directory isNone: |
directory = win32FontDirectory() |
fontext = get_fontext_synonyms(fontext) |
key, items =None, {} |
for fontdir in MSFontDirectories: |
try: |
local = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, fontdir) |
exceptOSError: |
continue |
ifnot local: |
files = [] |
for ext in fontext: |
files.extend(glob.glob(os.path.join(directory, '*.'+ext))) |
return files |
try: |
for j in sm.range(winreg.QueryInfoKey(local)[1]): |
try: |
key, direc, any= winreg.EnumValue(local, j) |
ifnot os.path.dirname(direc): |
direc = os.path.join(directory, direc) |
direc = os.path.abspath(direc).lower() |
if os.path.splitext(direc)[1][1:] in fontext: |
items[direc] =1 |
exceptEnvironmentError: |
continue |
exceptWindowsError: |
continue |
returnlist(items.keys()) |
finally: |
winreg.CloseKey(local) |
returnNone |
defOSXFontDirectory(): |
'' |
Return the system font directories for OS X. This is done by |
starting at the list of hardcoded paths in |
:attr:`OSXFontDirectories` and returning all nested directories |
within them. |
'' |
fontpaths = [] |
for fontdir in OSXFontDirectories: |
try: |
if os.path.isdir(fontdir): |
fontpaths.append(fontdir) |
for dirpath, dirs, _files in os.walk(fontdir): |
fontpaths.extend([os.path.join(dirpath, d) for d in dirs]) |
except (IOError, OSError, TypeError, ValueError): |
pass |
return fontpaths |
defOSXInstalledFonts(directory=None, fontext='ttf'): |
'' |
Get list of font files on OS X - ignores font suffix by default. |
'' |
if directory isNone: |
directory = OSXFontDirectory() |
fontext = get_fontext_synonyms(fontext) |
files = [] |
for path in directory: |
if fontext isNone: |
files.extend(glob.glob(os.path.join(path, '*'))) |
else: |
for ext in fontext: |
files.extend(glob.glob(os.path.join(path, '*.'+ext))) |
files.extend(glob.glob(os.path.join(path, '*.'+ext.upper()))) |
return files |
defx11FontDirectory(): |
'' |
Return the system font directories for X11. This is done by |
starting at the list of hardcoded paths in |
:attr:`X11FontDirectories` and returning all nested directories |
within them. |
'' |
fontpaths = [] |
for fontdir in X11FontDirectories: |
try: |
if os.path.isdir(fontdir): |
fontpaths.append(fontdir) |
for dirpath, dirs, _files in os.walk(fontdir): |
fontpaths.extend([os.path.join(dirpath, d) for d in dirs]) |
except (IOError, OSError, TypeError, ValueError): |
pass |
return fontpaths |
defget_fontconfig_fonts(fontext='ttf'): |
'' |
Grab a list of all the fonts that are being tracked by fontconfig |
by making a system call to ``fc-list``. This is an easy way to |
grab all of the fonts the user wants to be made available to |
applications, without needing knowing where all of them reside. |
'' |
fontext = get_fontext_synonyms(fontext) |
fontfiles = {} |
try: |
pipe = subprocess.Popen(['fc-list', '', 'file'], |
stdout=subprocess.PIPE) |
output = pipe.communicate()[0] |
exceptOSError: |
# Calling fc-list did not work, so we'll just return nothing |
return fontfiles |
output = output.decode('utf8') |
if pipe.returncode 0: |
for line in output.split('n'): |
fname = line.split(':')[0] |
if (os.path.splitext(fname)[1][1:] in fontext and |
os.path.exists(fname)): |
fontfiles[fname] =1 |
return fontfiles |
deffindSystemFonts(fontpaths=None, fontext='ttf'): |
'' |
Search for fonts in the specified font paths. If no paths are |
given, will use a standard set of system paths, as well as the |
list of fonts tracked by fontconfig if fontconfig is installed and |
available. A list of TrueType fonts are returned by default with |
AFM fonts as an option. |
'' |
fontfiles = {} |
fontexts = get_fontext_synonyms(fontext) |
if fontpaths isNone: |
if sys.platform 'win32': |
fontdir = win32FontDirectory() |
fontpaths = [fontdir] |
# now get all installed fonts directly.. |
for f in win32InstalledFonts(fontdir): |
base, ext = os.path.splitext(f) |
iflen(ext) >1and ext[1:].lower() in fontexts: |
fontfiles[f] =1 |
else: |
# check for OS X & load its fonts if present |
if sys.platform 'darwin': |
fontpaths = [] |
for f in OSXInstalledFonts(fontext=fontext): |
fontfiles[f] =1 |
else: |
# Otherwise, check X11. |
fontpaths = x11FontDirectory() |
for f in get_fontconfig_fonts(fontext): |
fontfiles[f] =1 |
elifisinstance(fontpaths, six.string_types): |
fontpaths = [fontpaths] |
for path in fontpaths: |
files = [] |
for ext in fontexts: |
files.extend(glob.glob(os.path.join(path, '*.'+ext))) |
files.extend(glob.glob(os.path.join(path, '*.'+ext.upper()))) |
for fname in files: |
abs_path = os.path.abspath(fname) |
# Handle dirs which look like font files, but may contain font |
# files |
if os.path.isdir(abs_path): |
fontpaths.append(abs_path) |
else: |
fontfiles[abs_path] =1 |
return [fname for fname in fontfiles.keys() if os.path.exists(fname)] |
defweight_as_number(weight): |
'' |
Return the weight property as a numeric value. String values |
are converted to their corresponding numeric value. |
'' |
ifisinstance(weight, str): |
try: |
weight = weight_dict[weight.lower()] |
exceptKeyError: |
weight =400 |
elif weight inrange(100, 1000, 100): |
pass |
else: |
raiseValueError('weight not a valid integer') |
return weight |
classFontEntry(object): |
'' |
A class for storing Font properties. It is used when populating |
the font lookup dictionary. |
'' |
def__init__(self, fname='', name='', style='normal', variant='normal', |
weight='normal', stretch='normal', size='medium'): |
self.fname = fname |
self.name = name |
self.style = style |
self.variant = variant |
self.weight = weight |
self.stretch = stretch |
try: |
self.size =str(float(size)) |
exceptValueError: |
self.size = size |
def__repr__(self): |
return'<Font '%s' (%s) %s%s%s%s>'% ( |
self.name, os.path.basename(self.fname), self.style, self.variant, |
self.weight, self.stretch) |
defttfFontProperty(fpath, font): |
'' |
A function for populating the :class:`FontKey` by extracting |
information from the TrueType font file. |
*font* is a :class:`FT2Font` instance. |
'' |
props = getPropDict(font) |
name = props[(1, 0, 0, 1)].decode() |
# Styles are: italic, oblique, and normal (default) |
try: |
sfnt2 = props[(1, 0, 0, 2)] |
except: |
sfnt2 =None |
try: |
sfnt4 = props[(1, 0, 0, 4)] |
except: |
sfnt4 =None |
if sfnt2: |
sfnt2 = sfnt2.lower().decode() |
else: |
sfnt2 ='' |
if sfnt4: |
sfnt4 = sfnt4.lower().decode() |
else: |
sfnt4 ='' |
if sfnt4.find('oblique') >=0: |
style ='oblique' |
elif sfnt4.find('italic') >=0: |
style ='italic' |
elif sfnt2.find('regular') >=0: |
style ='normal' |
else: |
style ='normal' |
# Variants are: small-caps and normal (default) |
# !!!! Untested |
if name.lower() in ['capitals', 'small-caps']: |
variant ='small-caps' |
else: |
variant ='normal' |
# Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), |
# 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) |
# lighter and bolder are also allowed. |
weight =None |
for w in weight_dict.keys(): |
if sfnt4.find(w) >=0: |
weight = w |
break |
ifnot weight: |
weight =400 |
weight = weight_as_number(weight) |
# Stretch can be absolute and relative |
# Absolute stretches are: ultra-condensed, extra-condensed, condensed, |
# semi-condensed, normal, semi-expanded, expanded, extra-expanded, |
# and ultra-expanded. |
# Relative stretches are: wider, narrower |
# Child value is: inherit |
if (sfnt4.find('narrow') >=0or sfnt4.find('condensed') >=0or |
sfnt4.find('cond') >=0): |
stretch ='condensed' |
elif sfnt4.find('demi cond') >=0: |
stretch ='semi-condensed' |
elif sfnt4.find('wide') >=0or sfnt4.find('expanded') >=0: |
stretch ='expanded' |
else: |
stretch ='normal' |
# Sizes can be absolute and relative. |
# Absolute sizes are: xx-small, x-small, small, medium, large, x-large, |
# and xx-large. |
# Relative sizes are: larger, smaller |
# Length value is an absolute font size, e.g. 12pt |
# Percentage values are in 'em's. Most robust specification. |
# !!!! Incomplete |
size ='scalable' |
return FontEntry(fpath, name, style, variant, weight, stretch, size) |
defafmFontProperty(fontpath, font): |
'' |
A function for populating a :class:`FontKey` instance by |
extracting information from the AFM font file. |
*font* is a class:`AFM` instance. |
'' |
name = font.get_familyname() |
fontname = font.get_fontname().lower() |
# Styles are: italic, oblique, and normal (default) |
if font.get_angle() !=0or name.lower().find('italic') >=0: |
style ='italic' |
elif name.lower().find('oblique') >=0: |
style ='oblique' |
else: |
style ='normal' |
# Variants are: small-caps and normal (default) |
# !!!! Untested |
if name.lower() in ['capitals', 'small-caps']: |
variant ='small-caps' |
else: |
variant ='normal' |
# Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), |
# 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) |
# lighter and bolder are also allowed. |
weight = weight_as_number(font.get_weight().lower()) |
# Stretch can be absolute and relative |
# Absolute stretches are: ultra-condensed, extra-condensed, condensed, |
# semi-condensed, normal, semi-expanded, expanded, extra-expanded, |
# and ultra-expanded. |
# Relative stretches are: wider, narrower |
# Child value is: inherit |
if (fontname.find('narrow') >=0or fontname.find('condensed') >=0or |
fontname.find('cond') >=0): |
stretch ='condensed' |
elif fontname.find('demi cond') >=0: |
stretch ='semi-condensed' |
elif fontname.find('wide') >=0or fontname.find('expanded') >=0: |
stretch ='expanded' |
else: |
stretch ='normal' |
# Sizes can be absolute and relative. |
# Absolute sizes are: xx-small, x-small, small, medium, large, x-large, |
# and xx-large. |
# Relative sizes are: larger, smaller |
# Length value is an absolute font size, e.g. 12pt |
# Percentage values are in 'em's. Most robust specification. |
# All AFM fonts are apparently scalable. |
size ='scalable' |
return FontEntry(fontpath, name, style, variant, weight, stretch, size) |
defcreateFontList(fontfiles, fontext='ttf'): |
'' |
A function to create a font lookup list. The default is to create |
a list of TrueType fonts. An AFM font list can optionally be |
created. |
'' |
#FIXME: This function is particularly difficult to debug |
fontlist = [] |
# Add fonts from list of known font files. |
seen = {} |
for fpath in fontfiles: |
logger.debug('createFontDict %s', fpath) |
fname = os.path.split(fpath)[1] |
if fname in seen: |
continue |
else: |
seen[fname] =1 |
if fontext 'afm': |
try: |
fh =open(fpath, 'r') |
except: |
logger.error( |
'Could not open font file %s', fpath, exc_info=True) |
continue |
try: |
try: |
font = afm.AFM(fh) |
finally: |
fh.close() |
exceptRuntimeError: |
logger.error( |
'Could not parse font file %s', fpath, exc_info=True) |
continue |
try: |
prop = afmFontProperty(fpath, font) |
exceptException: |
logger.error( |
'Could not covert font to FontEntry for file %s', fpath, |
exc_info=True |
) |
continue |
else: |
_, ext = os.path.splitext(fpath) |
try: |
if ext.lower() '.ttc': |
collection = TTCollection(str(fpath)) |
try: |
props = [] |
for font in collection.fonts: |
props.append(ttfFontProperty(fpath, font)) |
fontlist.extend(props) |
continue |
exceptException: |
logger.error( |
'Could not covert font to FontEntry for file %s', |
fpath, exc_info=True |
) |
continue |
else: |
font = TTFont(str(fpath)) |
except (RuntimeError, TTLibError): |
logger.error( |
'Could not open font file %s', fpath, exc_info=True) |
continue |
exceptUnicodeError: |
logger.error( |
'Cannot handle unicode file: %s', fpath, exc_info=True) |
continue |
try: |
prop = ttfFontProperty(fpath, font) |
exceptException: |
logger.error( |
'Could not covert font to FontEntry for file %s', fpath, |
exc_info=True |
) |
continue |
fontlist.append(prop) |
return fontlist |
classFontProperties(object): |
'' |
A class for storing and manipulating font properties. |
The font properties are those described in the `W3C Cascading |
Style Sheet, Level 1 |
<http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ font |
specification. The six properties are: |
- family: A list of font names in decreasing order of priority. |
The items may include a generic font family name, either |
'serif', 'sans-serif', 'cursive', 'fantasy', or 'monospace'. |
In that case, the actual font to be used will be looked up |
from the associated rcParam in :file:`matplotlibrc`. |
- style: Either 'normal', 'italic' or 'oblique'. |
- variant: Either 'normal' or 'small-caps'. |
- stretch: A numeric value in the range 0-1000 or one of |
'ultra-condensed', 'extra-condensed', 'condensed', |
'semi-condensed', 'normal', 'semi-expanded', 'expanded', |
'extra-expanded' or 'ultra-expanded' |
- weight: A numeric value in the range 0-1000 or one of |
'ultralight', 'light', 'normal', 'regular', 'book', 'medium', |
'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', |
'extra bold', 'black' |
- size: Either an relative value of 'xx-small', 'x-small', |
'small', 'medium', 'large', 'x-large', 'xx-large' or an |
absolute font size, e.g. 12 |
The default font property for TrueType fonts (as specified in the |
default :file:`matplotlibrc` file) is:: |
sans-serif, normal, normal, normal, normal, scalable. |
Alternatively, a font may be specified using an absolute path to a |
.ttf file, by using the *fname* kwarg. |
The preferred usage of font sizes is to use the relative values, |
e.g. 'large', instead of absolute font sizes, e.g. 12. This |
approach allows all text sizes to be made larger or smaller based |
on the font manager's default font size. |
This class will also accept a `fontconfig |
<http://www.fontconfig.org/>`_ pattern, if it is the only argument |
provided. See the documentation on `fontconfig patterns |
<http://www.fontconfig.org/fontconfig-user.html>`_. This support |
does not require fontconfig to be installed. We are merely |
borrowing its pattern syntax for use here. |
Note that matplotlib's internal font manager and fontconfig use a |
different algorithm to lookup fonts, so the results of the same pattern |
may be different in matplotlib than in other applications that use |
fontconfig. |
'' |
def__init__(self, family=None, style=None, variant=None, weight=None, |
stretch=None, size=None, fname=None, _init=None): |
# if fname is set, it's a hardcoded filename to use |
# _init is used only by copy() |
self._family =None |
self._slant =None |
self._variant =None |
self._weight =None |
self._stretch =None |
self._size =None |
self._file =None |
# This is used only by copy() |
if _init isnotNone: |
self.__dict__.update(_init.__dict__) |
return |
if is_string_like(family): |
# Treat family as a fontconfig pattern if it is the only |
# parameter provided. |
if (style isNoneand variant isNoneand weight isNoneand |
stretch isNoneand size isNoneand fname isNone): |
self.set_fontconfig_pattern(family) |
return |
self.set_family(family) |
self.set_style(style) |
self.set_variant(variant) |
self.set_weight(weight) |
self.set_stretch(stretch) |
self.set_file(fname) |
self.set_size(size) |
def__hash__(self): |
l = [(k, getattr(self, 'get'+ k)()) for k insorted(self.__dict__)] |
returnhash(repr(l)) |
def__str__(self): |
returnstr((self._family, self._slant, self._variant, |
self._weight, self._stretch, self._size)) |
defget_family(self): |
'' |
Return a list of font names that comprise the font family. |
'' |
returnself._family |
defget_name(self): |
'' |
Return the name of the font that best matches the font |
properties. |
'' |
filename =str(fontManager.findfont(self)) |
if filename.endswith('.afm'): |
return afm.AFM(open(filename)).get_familyname() |
font = fontManager.findfont(self) |
return getPropDict(TTFont(str(font)))[(1, 0, 0, 1)] |
defget_style(self): |
'' |
Return the font style. Values are: 'normal', 'italic' or |
'oblique'. |
'' |
returnself._slant |
get_slant = get_style |
defget_variant(self): |
'' |
Return the font variant. Values are: 'normal' or |
'small-caps'. |
'' |
returnself._variant |
defget_weight(self): |
'' |
Set the font weight. Options are: A numeric value in the |
range 0-1000 or one of 'light', 'normal', 'regular', 'book', |
'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', |
'heavy', 'extra bold', 'black' |
'' |
returnself._weight |
defget_stretch(self): |
'' |
Return the font stretch or width. Options are: 'ultra-condensed', |
'extra-condensed', 'condensed', 'semi-condensed', 'normal', |
'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded'. |
'' |
returnself._stretch |
defget_size(self): |
'' |
Return the font size. |
'' |
returnself._size |
defget_size_in_points(self): |
ifself._size isnotNone: |
try: |
returnfloat(self._size) |
exceptValueError: |
pass |
default_size = fontManager.get_default_size() |
return default_size * font_scalings.get(self._size) |
defget_file(self): |
'' |
Return the filename of the associated font. |
'' |
returnself._file |
defset_family(self, family): |
'' |
Change the font family. May be either an alias (generic name |
is CSS parlance), such as: 'serif', 'sans-serif', 'cursive', |
'fantasy', or 'monospace', or a real font name. |
'' |
if family isNone: |
self._family =None |
else: |
if''!=b''andisinstance(family, bytes): |
family = family.decode('utf8') |
if is_string_like(family): |
family = [family] |
self._family = family |
set_name = set_family |
defset_style(self, style): |
'' |
Set the font style. Values are: 'normal', 'italic' or |
'oblique'. |
'' |
if style notin ('normal', 'italic', 'oblique', None): |
raiseValueError('style must be normal, italic or oblique') |
self._slant = style |
set_slant = set_style |
defset_variant(self, variant): |
'' |
Set the font variant. Values are: 'normal' or 'small-caps'. |
'' |
if variant notin ('normal', 'small-caps', None): |
raiseValueError('variant must be normal or small-caps') |
self._variant = variant |
defset_weight(self, weight): |
'' |
Set the font weight. May be either a numeric value in the |
range 0-1000 or one of 'ultralight', 'light', 'normal', |
'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', |
'demi', 'bold', 'heavy', 'extra bold', 'black' |
'' |
if weight isnotNone: |
try: |
weight =int(weight) |
if weight <0or weight >1000: |
raiseValueError() |
exceptValueError: |
if weight notin weight_dict: |
raiseValueError('weight is invalid') |
self._weight = weight |
defset_stretch(self, stretch): |
'' |
Set the font stretch or width. Options are: 'ultra-condensed', |
'extra-condensed', 'condensed', 'semi-condensed', 'normal', |
'semi-expanded', 'expanded', 'extra-expanded' or |
'ultra-expanded', or a numeric value in the range 0-1000. |
'' |
if stretch isnotNone: |
try: |
stretch =int(stretch) |
if stretch <0or stretch >1000: |
raiseValueError() |
exceptValueError: |
if stretch notin stretch_dict: |
raiseValueError('stretch is invalid') |
else: |
stretch =500 |
self._stretch = stretch |
defset_size(self, size): |
'' |
Set the font size. Either an relative value of 'xx-small', |
'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large' |
or an absolute font size, e.g. 12. |
'' |
if size isnotNone: |
try: |
size =float(size) |
exceptValueError: |
if size isnotNoneand size notin font_scalings: |
raiseValueError('size is invalid') |
self._size = size |
defset_file(self, file): |
'' |
Set the filename of the fontfile to use. In this case, all |
other properties will be ignored. |
'' |
self._file =file |
defcopy(self): |
''Return a deep copy of self'' |
return FontProperties(_init=self) |
defttfdict_to_fnames(d): |
'' |
flatten a ttfdict to all the filenames it contains |
'' |
fnames = [] |
for named in d.values(): |
for styled in named.values(): |
for variantd in styled.values(): |
for weightd in variantd.values(): |
for stretchd in weightd.values(): |
for fname in stretchd.values(): |
fnames.append(fname) |
return fnames |
defpickle_dump(data, filename): |
'' |
Equivalent to pickle.dump(data, open(filename, 'wb')) |
but closes the file to prevent filehandle leakage. |
'' |
fh =open(filename, 'wb') |
try: |
sm.cPickle.dump(data, fh) |
finally: |
fh.close() |
defpickle_load(filename): |
'' |
Equivalent to pickle.load(open(filename, 'rb')) |
but closes the file to prevent filehandle leakage. |
'' |
fh =open(filename, 'rb') |
try: |
data = sm.cPickle.load(fh) |
finally: |
fh.close() |
return data |
classFontManager: |
'' |
On import, the :class:`FontManager` singleton instance creates a |
list of TrueType fonts based on the font properties: name, style, |
variant, weight, stretch, and size. The :meth:`findfont` method |
does a nearest neighbor search to find the font that most closely |
matches the specification. If no good enough match is found, a |
default font is returned. |
'' |
# Increment this version number whenever the font cache data |
# format or behavior has changed and requires a existing font |
# cache files to be rebuilt. |
__version__=7 |
def__init__(self, size=None, weight='normal'): |
self._version =self.__version__ |
self.__default_weight = weight |
self.default_size = size |
paths = [] |
# Create list of font paths |
for pathname in ['TTFPATH', 'AFMPATH']: |
if pathname in os.environ: |
ttfpath = os.environ[pathname] |
if ttfpath.find(';') >=0: # win32 style |
paths.extend(ttfpath.split(';')) |
elif ttfpath.find(':') >=0: # unix style |
paths.extend(ttfpath.split(':')) |
else: |
paths.append(ttfpath) |
logger.debug('font search path %s', str(paths)) |
# Load TrueType fonts and create font dictionary. |
self.ttffiles = findSystemFonts(paths) + findSystemFonts() |
self.defaultFamily = { |
'ttf': 'Bitstream Vera Sans', |
'afm': 'Helvetica'} |
self.defaultFont = {} |
for fname inself.ttffiles: |
logger.debug('trying fontname %s', fname) |
if fname.lower().find('vera.ttf') >=0: |
self.defaultFont['ttf'] = fname |
break |
else: |
# use anything |
self.defaultFont['ttf'] =self.ttffiles[0] |
self.ttflist = createFontList(self.ttffiles) |
self.afmfiles = findSystemFonts(paths, fontext='afm') + |
findSystemFonts(fontext='afm') |
self.afmlist = createFontList(self.afmfiles, fontext='afm') |
self.defaultFont['afm'] =None |
self.ttf_lookup_cache = {} |
self.afm_lookup_cache = {} |
defget_default_weight(self): |
'' |
Return the default font weight. |
'' |
returnself.__default_weight |
defget_default_size(self): |
'' |
Return the default font size. |
'' |
returnself.default_size |
defset_default_weight(self, weight): |
'' |
Set the default font weight. The initial value is 'normal'. |
'' |
self.__default_weight = weight |
defupdate_fonts(self, filenames): |
'' |
Update the font dictionary with new font files. |
Currently not implemented. |
'' |
# !!!! Needs implementing |
raiseNotImplementedError |
# Each of the scoring functions below should return a value between |
# 0.0 (perfect match) and 1.0 (terrible match) |
defscore_family(self, families, family2): |
'' |
Returns a match score between the list of font families in |
*families* and the font family name *family2*. |
An exact match anywhere in the list returns 0.0. |
A match by generic font name will return 0.1. |
No match will return 1.0. |
'' |
global preferred_fonts |
family2 = family2.lower() |
for i, family1 inenumerate(families): |
family1 = family1.lower() |
if family1 in font_family_aliases: |
if family1 in ('sans', 'sans serif', 'modern'): |
family1 ='sans-serif' |
options = preferred_fonts[family1] |
options = [x.lower() for x in options] |
if family2 in options: |
idx = options.index(family2) |
return0.1* (float(idx) /len(options)) |
elif family1 family2: |
return0.0 |
return1.0 |
defscore_style(self, style1, style2): |
'' |
Returns a match score between *style1* and *style2*. |
An exact match returns 0.0. |
A match between 'italic' and 'oblique' returns 0.1. |
No match returns 1.0. |
'' |
if style1 style2: |
return0.0 |
elif style1 in ('italic', 'oblique') and |
style2 in ('italic', 'oblique'): |
return0.1 |
return1.0 |
defscore_variant(self, variant1, variant2): |
'' |
Returns a match score between *variant1* and *variant2*. |
An exact match returns 0.0, otherwise 1.0. |
'' |
if variant1 variant2: |
return0.0 |
else: |
return1.0 |
defscore_stretch(self, stretch1, stretch2): |
'' |
Returns a match score between *stretch1* and *stretch2*. |
The result is the absolute value of the difference between the |
CSS numeric values of *stretch1* and *stretch2*, normalized |
between 0.0 and 1.0. |
'' |
try: |
stretchval1 =int(stretch1) |
exceptValueError: |
stretchval1 = stretch_dict.get(stretch1, 500) |
try: |
stretchval2 =int(stretch2) |
exceptValueError: |
stretchval2 = stretch_dict.get(stretch2, 500) |
returnabs(stretchval1 - stretchval2) /1000.0 |
defscore_weight(self, weight1, weight2): |
'' |
Returns a match score between *weight1* and *weight2*. |
The result is the absolute value of the difference between the |
CSS numeric values of *weight1* and *weight2*, normalized |
between 0.0 and 1.0. |
'' |
try: |
weightval1 =int(weight1) |
exceptValueError: |
weightval1 = weight_dict.get(weight1, 500) |
try: |
weightval2 =int(weight2) |
exceptValueError: |
weightval2 = weight_dict.get(weight2, 500) |
returnabs(weightval1 - weightval2) /1000.0 |
defscore_size(self, size1, size2): |
'' |
Returns a match score between *size1* and *size2*. |
If *size2* (the size specified in the font file) is 'scalable', this |
function always returns 0.0, since any font size can be generated. |
Otherwise, the result is the absolute distance between *size1* and |
*size2*, normalized so that the usual range of font sizes (6pt - |
72pt) will lie between 0.0 and 1.0. |
'' |
if size2 'scalable': |
return0.0 |
# Size value should have already been |
try: |
sizeval1 =float(size1) |
exceptValueError: |
sizeval1 =self.default_size * font_scalings(size1) |
try: |
sizeval2 =float(size2) |
exceptValueError: |
return1.0 |
returnabs(sizeval1 - sizeval2) /72.0 |
deffindfont(self, prop, fontext='ttf', directory=None, |
fallback_to_default=True, rebuild_if_missing=True): |
'' |
Search the font list for the font that most closely matches |
the :class:`FontProperties` *prop*. |
:meth:`findfont` performs a nearest neighbor search. Each |
font is given a similarity score to the target font |
properties. The first font with the highest score is |
returned. If no matches below a certain threshold are found, |
the default font (usually Vera Sans) is returned. |
`directory`, is specified, will only return fonts from the |
given directory (or subdirectory of that directory). |
The result is cached, so subsequent lookups don't have to |
perform the O(n) nearest neighbor search. |
If `fallback_to_default` is True, will fallback to the default |
font family (usually 'Bitstream Vera Sans' or 'Helvetica') if |
the first lookup hard-fails. |
See the `W3C Cascading Style Sheet, Level 1 |
<http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation |
for a description of the font finding algorithm. |
'' |
ifnotisinstance(prop, FontProperties): |
prop = FontProperties(prop) |
fname = prop.get_file() |
if fname isnotNone: |
logger.debug('findfont returning %s', fname) |
return fname |
if fontext 'afm': |
font_cache =self.afm_lookup_cache |
fontlist =self.afmlist |
else: |
font_cache =self.ttf_lookup_cache |
fontlist =self.ttflist |
if directory isNone: |
cached = font_cache.get(hash(prop)) |
if cached: |
return cached |
best_score =1e64 |
best_font =None |
for font in fontlist: |
fname = font.fname |
if (directory isnotNoneand |
os.path.commonprefix([fname, directory]) != directory): |
continue |
# Matching family should have highest priority, so it is multiplied |
# by 10.0 |
score = |
self.score_family(prop.get_family(), font.name) *10.0+ |
self.score_style(prop.get_style(), font.style) + |
self.score_variant(prop.get_variant(), font.variant) + |
self.score_weight(prop.get_weight(), font.weight) + |
self.score_stretch(prop.get_stretch(), font.stretch) + |
self.score_size(prop.get_size(), font.size) |
if score < best_score: |
best_score = score |
best_font = font |
if score 0: |
break |
if best_font isNoneor best_score >=10.0: |
if fallback_to_default: |
warnings.warn( |
'findfont: Font family %s not found. Falling back to %s'% |
(prop.get_family(), self.defaultFamily[fontext])) |
default_prop = prop.copy() |
default_prop.set_family(self.defaultFamily[fontext]) |
returnself.findfont(default_prop, fontext, directory, False) |
else: |
# This is a hard fail -- we can't find anything reasonable, |
# so just return the vera.ttf |
warnings.warn( |
'findfont: Could not match %s. Returning %s'% |
(prop, self.defaultFont[fontext]), |
UserWarning) |
result =self.defaultFont[fontext] |
else: |
logger.debug( |
'findfont: Matching %s to %s (%s) with score of %f', |
prop, best_font.name, best_font.fname, best_score |
) |
result = best_font.fname |
ifnot os.path.isfile(result): |
if rebuild_if_missing: |
logger.debug( |
'findfont: Found a missing font file. Rebuilding cache.') |
_rebuild() |
return fontManager.findfont( |
prop, fontext, directory, True, False) |
else: |
raiseValueError('No valid font could be found') |
if directory isNone: |
font_cache[hash(prop)] = result |
return result |
_is_opentype_cff_font_cache = {} |
defis_opentype_cff_font(filename): |
'' |
Returns True if the given font is a Postscript Compact Font Format |
Font embedded in an OpenType wrapper. Used by the PostScript and |
PDF backends that can not subset these fonts. |
'' |
if os.path.splitext(filename)[1].lower() '.otf': |
result = _is_opentype_cff_font_cache.get(filename) |
if result isNone: |
fd =open(filename, 'rb') |
tag = fd.read(4) |
fd.close() |
result = (tag 'OTTO') |
_is_opentype_cff_font_cache[filename] = result |
return result |
returnFalse |
fontManager =None |
_fmcache = os.path.join(get_configdir(), 'fontList.cache') |
def_rebuild(): |
global fontManager |
fontManager = FontManager() |
pickle_dump(fontManager, _fmcache) |
logger.debug('generated new fontManager') |
# The experimental fontconfig-based backend. |
ifUSE_FONTCONFIGand sys.platform !='win32': |
import re |
deffc_match(pattern, fontext): |
fontexts = get_fontext_synonyms(fontext) |
try: |
pipe = subprocess.Popen(['fc-match', '-sv', pattern], |
stdout=subprocess.PIPE) |
output = pipe.communicate()[0] |
exceptOSError: |
returnNone |
if pipe.returncode 0: |
for match in _fc_match_regex.finditer(output): |
file= match.group(1) |
if os.path.splitext(file)[1][1:] in fontexts: |
returnfile |
returnNone |
_fc_match_regex = re.compile(r'sfile:s+'([^']*)'') |
_fc_match_cache = {} |
deffindfont(prop, fontext='ttf'): |
ifnot is_string_like(prop): |
prop = prop.get_fontconfig_pattern() |
cached = _fc_match_cache.get(prop) |
if cached isnotNone: |
return cached |
result = fc_match(prop, fontext) |
if result isNone: |
result = fc_match(':', fontext) |
_fc_match_cache[prop] = result |
return result |
else: |
try: |
fontManager = pickle_load(_fmcache) |
if (nothasattr(fontManager, '_version') or |
fontManager._version != FontManager.__version__): |
_rebuild() |
else: |
fontManager.default_size =None |
logger.debug('Using fontManager instance from %s', _fmcache) |
except: |
_rebuild() |
deffindfont(prop, **kw): |
global fontManager |
font = fontManager.findfont(prop, **kw) |
return font |
Copy lines Copy permalink
Main / Comics / Font s60v3 full emoji
Name: Font s60v3 full emoji File size: 273mb Language: English Rating: 3/10 |
If you're all set to use the Emoji application, you first need to adjust its font to match your phone's settings. If you feel that the Emoji are not being displayed. 6 Abr support full Unicode and Emoji for Nokia feature pack 1 (FP1). suitable for damage caused this font on your Mobile. Do it with your own risk. In this version, full support unicode fonts on android HH and fit. For those who prefer shade ga Emoji, cb aja pake this version. suitable for app.
20 Feb 1. Comic Sans v (E63|E71|E72|E6|Anna|Belle|Android)- Download via Mediafire - (5MB) 2. Jambono V If you're all set to use the Emoji application, you first need to adjust its font to match your. 9 Mar Monotype Imaging FlipFont™ v S60v3+s60v5 Signed + 37 font AmericanType v [sis mouse over the emoticon to findout the code.
Download ratusan font keren buat hp symbian s60v3. Free download fonts for symbian s60v3. Di versi ini s60v3. Fonts america v7x unicode full emoji kiva. Lagi Dengan Postingan Saya Yang Berjudul Font Ttf Symbian Full Unicode free download gratis kumpulan font TTF unicode.S60V3 ihint full emoji terbaru high. Download Font Ttf S60v3 Full Unicode Free Download. FONT TTF UNICODE SYMBIAN S60V3 IHINT FULL EMOJI TERBARU HIGH MEMORI AND LOW. 31 Des ane juga dah sediain dua versi low fw dan full emoji na gan biar gg to yg gg suka emoji n silksajavat.com low fw ini work tuk s60v3 pre-fp1. Moddingtemagame Font Unicode v7x Full Emoji Mod by Kiva s60v2 s60v3 Download Kika Emoji Keyboard GIF Free Terbaru 9 - merupakan aplikasi keyboard.
More:
Main / Simulation / Font s60v2 blog
Name: Font s60v2 blog File size: 896mb Language: English Rating: 10/10 |
13 Des Instant downloads for 46 free comic sans fonts. For you professionals, 13 are % free for commercial-use! Koleksi besar cartoon font s60v2. 22 Jan partiescrise · Blog Symbian fonts tekton ttf unicode v by ihint support belle navibar. Download Font Ttf Android S60v2. Membuat Kumpulan font ttf full unicode untuk symbian s60v2 s60v3 s60v5. Symbian software zone. milansmanshop.com · Fonts milansmanshop.com · milansmanshop.com · Mono milansmanshop.com · Segoe print milansmanshop.com · Zonamobile · milansmanshop.com · milansmanshop.com · Zonamix.
sisboomfinal.v (s60v2) · Tante full.3gp · milansmanshop.com · nosferatu-v milansmanshop.com · About me · Aplikasi Symbian · Blog · Font ttf s60v2 · Java Game. 24 Jun Well, today i wanna share one of the best font ever for you nokia symbian 2nd users. this font is just nice. and beside, this also has a small size. Nokia Goudy Font S60v2. Nokia Goudy Font Symbian mobile phone. Download Free Nokia Goudy Font S60v2 milansmanshop.comus Blog Archive. ▻ (26).
Nokia Sans Urdu fonts for s60v2 - Nokia Urdu fonts for s60v2 (,,, ,n70,n72 etc). After installation please restart your phone. To remove these. 5 Ags Dynamic Pinterest Pinit Button for milansmanshop.com, Dynamic Pinterest Pinit Blackberry Font milansmanshop.com, Blackberry Font S60V2 Blackberry Font. 15 Jan Aplikasi edit foto keren s60v2 - Blog kali ini memberikan tutorial edit foto dan koleksi font ttf keren unik untuk symbian s60v2 s60v3 font. 13 May S60v2 mobile phone is usually only able to use the fonts with the extension gdr, but with this Before practicing the steps below, first download ttf fonts and files and also files milansmanshop.com milansmanshop.com Free Blog Content. Chiller font font chiller v7x low milansmanshop.com keren to s60v2 mu. Download j cole forest hills drive album zip. boediwbs by ihint dalam postingan kali ini boedi wbs blog atau http //milansmanshop.com shared font.
15 Jun Font Unicode v7x Full Emoji Mod by Kiva s60v2 s60v3 Sekedar mau share Multi Clipboard Lastest Version free downoad for Mobile Phone in. DOWNLOAD FONT S60V2 SIS. Blog; Android; iOS; Windows; Resources In addition, S60v2 you can browse television shows specifically by the channels or . He 's Alyn Shipton in download font s60v2 blackberry of an movie at Cheltenham Blogs do plug-in imposed CDs that know well added and are charged with. Blog: hydra router crack download. Posted by getdata recover my files v5 crack how to crack used motor oil on May 2, at p.m. virtual dj cracked.
At the moment there are several ways to use non-system fonts on a website. We will focus on the two least complicated, least expensive systems, Google Web. 26 Des Aplikasi Penguat Sinyal Symbian s60v2 milansmanshop.coma buat buka-buka File Hp orang dan hp cina java Posted by Admin Symbian Blog. Font ttf milansmanshop.com -brother-tube-galore 2 [Top rated] free download video tokyo. 25 Oct S60v2 Softwares. S60v2 Softwares Urdu Font just 4 N · Urdu Font just 4 N Loading. Dynamic Views theme. Powered by Blogger. 22 Sep Download File. Home > S60v2 Apps > font remover s60 v2. *: font remover s60 v2 *: S60v2 Apps Blogs and Forums code: * Search.
More:
LOS ORIGINALES DE POMADA - UN DISCO CUALQUIERA (NUEVO VIDEO 2013) - YouTube. By 9800s Kris Bowers - Rigamortis (Kendrick Lamar Cover) Kendrick LamarJazz FestivalPiano CoverYoutubeWatchesItunesPianosFilmsBeautiful. Photoshop Cs2 Portable Free Download here.
Starcraft Brood War Oblivion Download Full. Why Choosing Us? Creating high quality Korg PA Styles or Korg PA Sounds for Korg PA arranger keyboards usually takes too much time and effort. Furthermore, the quality of the resulting Korg Style may not be as expected nor of good musical taste if not composed and produced by experienced professional musicians. Therefore, getting your Korg PA Styles or Sets from professional music content providers and/or producers will be the best option to take advantage of the wide musical tastes produced and high quality styles found in professional Korg PA Sets which are marketed nowadays.
If you are serious about your music career or developing your hobby with Korg PA arranger keyboards, then it's time to consider enriching your musical experience with diverse genres of musical styles, and of course, selecting only the high quality styles. Do not waste your time creating and quantizing all Korg Style elements, instead, focus on your musical performance by using our diverse ready-made high quality Korg PA Styles.