diff options
author | Ben de Groot <yngwin@gmail.com> | 2012-07-30 02:08:21 +0800 |
---|---|---|
committer | Ben de Groot <yngwin@gmail.com> | 2012-07-30 02:08:21 +0800 |
commit | cfb081676340152543cb2d281743f573548bc9f0 (patch) | |
tree | 62648b4d561837ce6beb24fcdcf4c8245bb1137f /media-libs | |
parent | [dev-util/ohcount] Make repoman happy. (diff) | |
download | betagarden-cfb081676340152543cb2d281743f573548bc9f0.tar.gz betagarden-cfb081676340152543cb2d281743f573548bc9f0.tar.bz2 betagarden-cfb081676340152543cb2d281743f573548bc9f0.zip |
Remove infinality packages, they are in official tree now
Diffstat (limited to 'media-libs')
11 files changed, 0 insertions, 8950 deletions
diff --git a/media-libs/fontconfig-infinality/Manifest b/media-libs/fontconfig-infinality/Manifest deleted file mode 100644 index 5ed534e..0000000 --- a/media-libs/fontconfig-infinality/Manifest +++ /dev/null @@ -1,4 +0,0 @@ -AUX Xresources 1814 SHA256 edbc78ddf590ab9bdf19e6f34fedf6ecdc54c29da67c0d14f25c74e7ae8207a4 SHA512 0647e3a2ed6f68c8d1266de52288bac2fca9320aef1573e74f30bff0e0176c6a63c8c71d3d4aae764b5bf57fe3ca8f3f2906e1c51d8cb26c855bb9858490f3b0 WHIRLPOOL f41770a99158482b25d332a6fdb2d64d31d94c4ec95423e462ef44aecc54fa19391c31061d79305c6194bda83b23a59b019e29a507a7f0c9563decc7a07b17c1 -AUX infinality-settings.sh 36878 SHA256 e6d53cf67e52fb22eadc03a82212eef63cd68a63ec9b50fc82df5fd2c646778f SHA512 34f84579c4a536987a2420078bafd3bf22b4cc5ff73e3e2fa6a9cd008c088b8a80d1b05fe602c96a1c14a1b5143b6446394c3f16b004084c45a2b97ac993ec3b WHIRLPOOL 5a746700b9c979c9598d29a04b8c8688f95b2ced5fb40d72809e15e4ab1166a37ab14b9db6580bc9f8cf73335732b800d7f64d39946f74feac47d9d2241c5e42 -DIST fontconfig-infinality-20120619.tar.xz 18956 SHA256 56563ea3200fa9c9b0a269260115e93bb4a635cef073655bef8dbe541031cac6 SHA512 2b20dd6c459572d8864459c32b9a50cfa3757df9fbdab75528772be81dbe7de31d2e997c4047083270769ee80d5e110ca43a9bddaf8c771f70e4181cab7cfb56 WHIRLPOOL 9fb51dbd24e118b276a0e7688a5d8d1f3db4952a399ef076db62531bb13f48c5b7484f3664c0d8de6fc809ad37b76275a95124bea366d3a6bd4e847b5f354d2e -EBUILD fontconfig-infinality-20120619.ebuild 1069 SHA256 fd94327bd90cd6784df382a6787bdb431ff0c8e0783b0f7605ca60a5432c763e SHA512 44063190774180269d188e206e7f867b58ce0da6f9ae44f3de0d99cbc6bbdcb357890d6903484c12f69a4d5026768dfda99ea2326d61ff1b04dc87b34fbe175c WHIRLPOOL 8a239915ffce17832f1efbfe743a09fadff537a380a4ed63771747740a6f74d4ca8cf9bfff6e50d1a04509b92e6650f475bb85ef1ade43461d53dd7f7c33fe46 diff --git a/media-libs/fontconfig-infinality/files/Xresources b/media-libs/fontconfig-infinality/files/Xresources deleted file mode 100644 index d34e001..0000000 --- a/media-libs/fontconfig-infinality/files/Xresources +++ /dev/null @@ -1,32 +0,0 @@ -################################################################# -################## EXPLANATION OF SETTINGS ###################### -################################################################# - -# XFT settings are like a red-headed stepchild that should be beaten severely. -# These only affect legacy programs, and *parts* of some modern programs like -# google-chrome. We only deal with these settings because we have to, otherwise -# crap will slip by. I recommend using hintslight and autohint as the defaults -# normally in local.conf. The reason hintfull and autohint:0 is needed here -# because otherwise some programs will occassionally request slight hinting for -# a truetype font. When a program does this, Freetype automatically uses the -# autohinter, when you may actually want it to be rendered with the TT hinter, -# (if specified in local.conf). So setting this to hintfull guarantees that the -# TT font will be rendered with the TT hinter (assuming it is specified in -# /etc/fonts/local.conf to be rendered that way.) For TT fonts that you want -# rendered with autohint, specifiying that in the /etc/fonts/local.conf -# should be enough. But you might think that by setting this to hintfull -# that it's going to use Freetype's full autohinting (which we *completely* -# avoid) for fonts you want autohinted. This is where -# INFINALITY_FT_AUTOFIT_FORCE_SLIGHT_HINTING comes in. It tells freetype to -# use slight hinting on fonts set for autohinting, even if the program requests -# full autohinting. Freetype's full hinting only looks OK under certain -# circumstances. The goal of infinality is to make infinality hinting look -# good all the time. - -Xft.antialias: 1 -Xft.autohint: 0 -Xft.dpi: 96 -Xft.hinting: 1 -Xft.hintstyle: hintfull -Xft.lcdfilter: lcddefault -Xft.rgba: rgb diff --git a/media-libs/fontconfig-infinality/files/infinality-settings.sh b/media-libs/fontconfig-infinality/files/infinality-settings.sh deleted file mode 100644 index 6d0a858..0000000 --- a/media-libs/fontconfig-infinality/files/infinality-settings.sh +++ /dev/null @@ -1,1014 +0,0 @@ -################################################################## -### INFINALITY ENVIRONMENT VARIABLES FOR EXTRA RUN-TIME OPTIONS ## -################################################################## -# -# These environment variables require that their respective patches -# from http://www.infinality.net have been applied to the Freetype -# installation you are using. They will do abolutely -# nothing otherwise! -# -# Of course, the per-user settings will override the system-wide -# settings. Default values indicated below will be used when the -# environment variables below are not defined. -# -# When I say "Default:" below, I'm referring to the default if no -# environment variables are set. Generally this ends up being -# whatever Freetype's default is set to. -# - - -################################################################## -# EXAMPLES -# -# Please see 3/4 down in this file for examples of different settings. -# - - - - - - -################################################################# -################## EXPLANATION OF SETTINGS ###################### -################################################################# - - - -################################################################## -# INFINALITY_FT_FILTER_PARAMS -# -# This is a modified version of the patch here: -# http://levelsofdetail.kendeeter.com/2008/12/dynamic_fir_filter_patch.html -# -# Allows you to adjust the FIR filter at runtime instead of at -# compile time. The idea is to have values add up to 100, and be -# symmetrical around the middle value. If the values add up to -# more than 100, the glyphs will appear darker. If less than 100, -# lighter. I recommend using this method to make glyphs darker -# or lighter globally as opposed to using the gamma option (see note in -# the gamma option). -# -# Here are some samples of various filter parameters: -# -# (this has been changed to use integers between 0 and 100 to -# avoid problems with regional differences like comma for decimal point) -# -# -# Strong Extra Smooth "15 20 30 20 15" (extra smooth, natural weight) -# Extra Smooth "20 20 30 20 20" (extra smooth, extra weight) -# Smooth "15 20 32 20 15" (smooth, natural weight) -# Stronger Gibson "11 22 38 22 11" (smooth, extra weight) -# Gibson "11 22 33 22 11" (smooth, natural weight) -# Freetype Light "00 33 34 33 00" (sharp, natural weight) # freetype's "light" LCD filter -# Freetype Default "06 25 44 25 06" (sharp, extra weight) # freetype's default -# Extra Sharp "00 35 35 35 00" (extra sharp, extra weight) # freetype's "light" LCD filter on acid -# -# -# Windows uses something more sharp, maybe along the lines of Freetype's default -# -# Default if no ENV_VARS present: [Freetype's default] -# Recommended: "11 22 38 22 11" (too dark / smooth for some) -# -# Example 1: export INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -# - -INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" - - - -################################################################## -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH -# -# This performs analysis on each glyph and determines an amount -# to shift the glyph, left or right, so that it aligns better to -# pixel boundaries. -# -# This results in subtley cleaner looking stems, at the expense of -# proper distances between glyphs. This is only active for sizes -# 10 px or greater and does not apply to bold or italic fonts. -# -# There are also exceptions on a small number of fonts that I've -# not been able to render nicely with alignment enabled. In those -# cases, a forced translation is applied instead. -# -# Possible values: -# 0 through 100 - think of as percentage of strength -# -# 0 corresponds to no shifting whatsoever. In other words, OFF. -# -# 100 corresponds to a full move to a snap zone defined by -# the snapping algorithm, be it left or right. This -# is the full amount any glyph could be moved in order to make it -# align to the pixel. -# -# Values inbetween act as caps. If the algorithm determines that it -# wants to move the glyph .33 of a pixel to the left, but the value -# is set to 50 (i.e. 50%), then the maximum move that would be allowed -# is 50% of half a pixel, in other words .25. So instead of .33 the -# glyph is moved .25 of a pixel. -# -# For a subtle effect that doesn't dramatically affect the glyph, use -# 25 for this and 25 for INFINALITY_FT_STEM_FITTING_STRENGTH -# -# Default if no ENV_VARS present: 0 -# Recommended if you want to use it: 100 - -INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25 - - - -################################################################## -# INFINALITY_FT_STEM_FITTING_STRENGTH -# -# This performs analysis on each glyph and determines an amount -# to horizontally scale the glyph, so that stems align better to -# pixel boundaries. An emboldening (or anti-emboldening) is -# performed afterward to account for stem width exaggeration. -# -# This results in subtley cleaner looking fonts, at the expense of -# proper distances between glyphs and slightly misshapen glyphs. -# This is only active for sizes 10 px or greater and does not -# apply to bold or italic fonts. -# -# There are also exceptions on a small number of fonts that I've -# not been able to render nicely with fitting enabled. In those -# cases, a forced translation is applied instead. -# -# -# Possible values: -# 0 through 100 - think of as percentage of strength -# -# 0 corresponds to no stretching whatsoever. In other words, OFF. -# -# 100 corresponds to a full pixel stretch, be outward or inward. This -# is the full amount any glyph could be stretched in order to make it -# align to a pixel boundary. Which direction is chosen is part -# of the art of what I'm trying to do in the code. ;) -# -# -# Values inbetween act as caps. If the algorithm determines that it -# wants to stretch the glyph .75 of a pixel outward, but the value -# is set to 50 (i.e. 50%), then the maximum move that would be allowed -# is 50% of a pixel, in other words .50. So instead of .75 the -# glyph is stretched .50 of a pixel. -# -# For a subtle effect that doesn't dramatically affect the glyph, use -# 25 for this and 25 for INFINALITY_FT_STEM_FITTING_STRENGTH -# -# Default if no ENV_VARS present: 0 -# Recommended if you want to use it: 100 - -INFINALITY_FT_STEM_FITTING_STRENGTH=25 - - - -################################################################## -# INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE -# -# This allows you to set a ppem at which alignment and fitting -# will reach 100%. As glyphs become larger, more dramatic -# snapping will not affect the glyph shape as much, so it makes -# sense to allow this. -# -# For fonts that are 10 ppem, the values set above for -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH and -# INFINALITY_FT_STEM_FITTING_STRENGTH will be used. As the ppem -# gradually becomes larger, so will the strength settings, and -# they will reach 100% at the ppem you specify here. -# -# This is a simple linear scale. -# -# Possible values: -# 0 means to not use this feature -# -# 11 and up will set the 100% level to that ppem value -# -# Anything else is officially undefined, but I still bound it internally. -# -# Default if no ENV_VARS present: 0 - -INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40 - - - -################################################################## -# INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS -# -# This applies largely to certain MS fonts, but some others as well. -# it will apply known good settings on a font-by-font basis, regardless -# of the other settings above or below. -# -# - Use known values for selected fonts & ppems that are known to look -# ok with 100: -# -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH -# INFINALITY_FT_STEM_FITTING_STRENGTH -# -# - Use various internal tweaks like compatible widths and other -# font-specific hacks. -# - Use gamma, brightness or contrast adjustments automatically -# on certain fonts. Global settings will still apply afterwards. -# - Enable various forced settings on selective fonts during -# rasterization and stem_alignment. -# -# If set to TRUE, this will use 100 regardless of the values you have -# specified above. It will not affect fonts that are not in this -# small list. -# -# Possible values: -# FALSE means to not use this feature -# -# TRUE will enable this feature -# -# Default if no ENV_VARS present: FALSE -# Recommended: TRUE -# - -INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################################################################## -# INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH -# -# This enables an algorithm found in ChromeOS for sharpening the -# appearance of glyphs. It is based off this patch: -# -# http://codereview.chromium.org/3298011/diff/9001/media-libs/freetype/files/freetype-2.3.11-lcd-sharpen.patches -# -# It gives glyphs a more "grainy" look through some gamma -# correction. It does tend to thin out vertical stems, which -# may be a feature or a bug depending on your taste ;) -# -# -# Possible values: -# 0 through 100 - think of as percentage of strength -# -# 0 corresponds to no sharpening whatsoever. In other words, OFF. -# -# 25 is good for a subtle effect. -# -# 50 corresponds to the default ChromeOS value. -# -# 100 corresponds to maximum sharpening. This usually results in -# something undesirable looking. -# -# -# As you increase this amount, it is good to decrease the gamma (2nd value) -# of INFINALITY_FT_PSEUDO_GAMMA, and possibly increase -# INFINALITY_FT_STEM_FITTING_STRENGTH and -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH, as it seems like the algorithm -# lightens stems that aren't fully on-pixel. -# -# Default if no ENV_VARS present: 0 -# Recommended: If you're going to use this filter - 50 - -INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 - - - -################################################################## -# INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH -# -# This enables an algorithm developed with the intention to sharpen -# fonts to look similarly to Windows. -# -# It gives glyphs a more "grainy" look, like the ChromeOS filter -# except it does so more selectively. This prevents the thinning -# of vertical stems that is noticible when a blanket gamma filter -# like the ChromeOS filter is applied. -# -# I also get a "cleaner" impression from the fonts with this Windows -# style filter. This filter was done by 100% experimentation, -# and there things that could probably be improved. -# -# Some may argue that I shouldn't be trying to take the shortcomings -# of the MS approach and bring them here. I disagree, as part -# of freedom is having the right to make your fonts look as -# shitty as you'd like. -# -# Using this filter does somewhat lessen the need to use stem -# fitting and stem alignment, as glyphs appear sharper. -# -# This setting can be used at the same time as the previous chromeOS -# sharpening, and happens after it in the code. -# -# -# Possible values: -# 0 through 100 - think of as percentage of strength -# -# 0 corresponds to no sharpening whatsoever. In other words, OFF. -# -# 10-25 is good for a subtle effect while not completely decimating glyphs. -# -# 50-75 corresponds to probably something in the range that Windows uses. -# -# 100 corresponds to maximum sharpening. -# -# -# Using a high value for this variable along with enabling the -# fringe filter (below) almost eliminates the need -# for INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT to be set to 100, -# and can instead be set at 0. (Setting -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT to 0 prevents missing -# stems in the middle of s. The drawback is that many fonts just look -# way too sharp and grainy at this setting. Your call.) -# -# Default if no ENV_VARS present: 0 -# Recommended if you want to use this filter: 65 - -INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=10 - - - -################################################################## -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT -# -# When using autohinting, horizontal stems you'd find in E, f, T, -, -# etc. are normally not snapped to full integer pixel heights, meaning -# that you will get a semi-dark fringe on these stems, above or -# below the black line of pixels: -# -# ########## -# ## -# ##------- -# ######### -# ## -# ##-------- -# ########## -# -# (- represents the semi-dark pixels) -# -# Setting this to 100 will force integer pixel heights. Setting it to -# zero will do what Freetype does by default. Anything inbetween will -# act as a weighted average of the two. -# -# This is disabled when the standard width is found (via voodoo) to be -# less than 1 pixel, in order to prevent the vanishing stem issues on -# letters with diagonal stems like a and s. -# -# Under most circumstances, this should be set at 100. If you choose to -# not set it to 100, you may want to set INFINALITY_FT_FRINGE_FILTER_STRENGTH -# to a non-zero value in order to reduce fringing. -# -# -# Possible values: -# 0 - default Freetype value -# 100 - a full pixel -# -# -# Default if no ENV_VARS present: 0 -# Recommended: 100 - -INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 - - - -################################################################## -# INFINALITY_FT_USE_VARIOUS_TWEAKS -# -# - Force autohint when no TT instructions present. -# - Artificially embolden horizontally only. -# - When artificially emboldening, maintain the glyph width. -# - Embolden light and thin-stemmed glyphs automatically. -# - Don't sharpen italics. -# -# Some fonts look bad when stem aligned at certain ppems, no matter -# what. I've put exceptions in to deal with these, included in -# these tweaks. Georgia and Lucida Grande are examples. -# -# -# Possible values: -# true - enable tweaks -# false - do not enable tweaks (do Freetype default) -# -# -# Default if no ENV_VARS present: false -# Recommended: true - -INFINALITY_FT_USE_VARIOUS_TWEAKS=true - - - -################################################################## -# INFINALITY_FT_GAMMA_CORRECTION -# -# This does a weighted gamma correction at the LCD filter phase -# PRIOR to the LCD filter. Unfortunately it does not however -# take into account the color on which the glyph is being rendered -# (or for that matter the color of the glyph), -# which would need to happen in X rendering. It is actually -# using the gamma function in calculations though. -# -# The first value indicates a px value, the second indicates a -# "gamma" value. All sizes less than the px value will be corrected -# on a weighted scale based on the second value. -# -# The gamma value is commonly between 0.0 and 3.0. Due to localization -# issues, the gamma value should be specified as it's actual value -# multiplied by 100. So a gamma of 1.3 would be 130. In practice, -# I'd stay between 40 and 250. -# -# -# Values 1 through 100 will darken the glyph -# Values greater than 100 will lighten the glyph -# -# -# Example 1: Darken glyphs that are less than 10 px. With some fonts -# even 5 or 6px is readable! -# export INFINALITY_FT_GAMMA_CORRECTION="10 60" -# -# Example 2: Lighten all glyphs (below 100px) -# export INFINALITY_FT_GAMMA_CORRECTION="100 150" -# -# Example 3: Do nothing -# export INFINALITY_FT_GAMMA_CORRECTION="0 100" -# -# Default: [No gamma correction] - -INFINALITY_FT_GAMMA_CORRECTION="0 100" - - - -################################################################## -# INFINALITY_FT_BRIGHTNESS -# -# This filter adjusts brightness, using the standard algorithm -# for brightness. It is applied AFTER the LCD filtering. -# -# For a Windows XP look, set brightness to something and contrast to 50 -# This will also tend to increase its sharpness. -# These values are relative and don't really mean anything -# however they are satisfactory for a range of appearances. -# Another tip is to use a gamma setting of "1000 110" or something -# over 100 to lighten things before processing. -# -# Default if no ENV_VARS present: 0 -# Dark XP Experience: -25 -# Light XP Experience: 40 -# -# Example: export INFINALITY_FT_BRIGHTNESS="-20" - -INFINALITY_FT_BRIGHTNESS="0" - - - -################################################################## -# INFINALITY_FT_CONTRAST -# -# This filter adjusts contrast, using the standard algorithm -# for contrast. It is applied AFTER the LCD filtering. -# -# For a Windows XP look, set brightness to -25 and contrast to 50 -# This will also tend to increase its sharpness. -# These values are relative and don't really mean anything -# however they are satisfactory for a range of appearances. -# Another tip is to use a gamma setting of "1000 110" or something -# over 100 to lighten things before processing. -# -# Default if no ENV_VARS present: 0 -# Dark or Light XP Experience: 50 -# -# Example: export INFINALITY_FT_CONTRAST="50" - -INFINALITY_FT_CONTRAST="0" - - - -################################################################## -# INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH -# -# This filter adjusts subpixel-rendered glyphs toward grayscale. -# Sometimes this is useful in getting a rendering more like -# OSX. -# -# Range: Integers 0 through 100 -# 0 represents no filtering -# 50 represents halfway between subpixel and grayscale -# 100 represents completely grayscale -# -# Default if no ENV_VARS present: 0 -# Recommended, if you want to use it: 30 -# -# Example: export INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH="33" - -INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH="0" - - - -################################################################## -# INFINALITY_FT_FRINGE_FILTER_STRENGTH -# -# This filter tries to remove the horizontal fringing that is found on -# default autohinted glyphs (similar to OSX-rendered glyphs). -# For example, an E may be rendered so that the middle horizontal -# stem is 100% black, but also has a horizonal row of pixels above -# it that is at 50% intensity. This makes the glyph look dirty, -# however it is technically accurate. -# -# This would be useful in cases where you have -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT set to something less than 100 -# but also can affect glyphs at 100, to some degree. -# -# Unless fonts are showing fringes in a way that annoys you, I recommend -# keeping it disabled, as it can slightly interfere with smooth appearance -# sometimes. -# -# -# Range: Integers 0 through 100 -# 0 represents no filtering -# 50 represents a 50% reduction of detected fringes -# 100 represents completely removing detected fringes -# -# -# Default if no ENV_VARS present: 0 -# Recommended, if you want to use it: 100 -# -# Example: export INFINALITY_FT_FRINGE_FILTER_STRENGTH="100" - -INFINALITY_FT_FRINGE_FILTER_STRENGTH="0" - - - -################################################################## -# INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH -# -# This post-filter darkens horizontal stems that autohint renders as semi-dark. -# Freetype will by default not force stems to render to pixel boundaries -# because it results in "vanishing stems". This happens on things like -# s S a and other glyphs with center diagonal stems. -# -# If you have INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT set to 100, -# you're telling it to force pixel boundaries, which can result in the -# vanishing stems. To get around this problem, I internally override the -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT setting if the stem width -# is less than a full pixel, regardless. This causes semi-dark stems, but -# at least there are stems there. -# -# This filter is intended to darken those semi-dark stems. I highly -# recommend using this, but setting to a low value like 10, because -# it is particularly sensitive right now, and can make thin fonts -# look weird otherwise. -# -# -# Range: Integers 0 through 100 -# 0 represents no darkening -# 50 represents a 50% increase toward 1 pixel in height -# 100 represents a full pixel of height -# -# -# Default if no ENV_VARS present: 0 -# Recommended, if you want to use it: 10 -# -# Example: export INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH="10" - -INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH="10" - - - -################################################################## -# INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH -# -# This post-filter darkens vertical stems less than 1 pixel that autohint -# renders as semi-dark. This applies mostly to thin fonts like -# Courier New, Raleway, and fonts with the word "Light" in the title or -# style. Although what autohint is doing is technically correct, it -# results in a bad looking rendering because it's too light, at small -# ppems. This filter tries to correct that. -# -# There is an aspect of this that is automatic, so it's safer to use -# larger values for this than the above horizontal ENV_VAR. However -# setting this higher has more impact on thinner fonts. So, I still -# recommend lower values. -# -# -# Range: Integers 0 through 100 -# 0 represents no darkening -# 50 represents a 50% increase (from current strength) toward 1 pixel -# 100 represents a full pixel of width -# -# -# Default if no ENV_VARS present: 0 -# Recommended, if you want to use it: 25 -# -# Example: export INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH="25" - -INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH="25" - - - -################################################################## -# INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS -# -# This will slightly stretch some glyphs vertically between 9px -# and 14px (inclusive). Some people may find this more -# aesthetically pleasing. This only applies to fonts that are -# using autohint. I used to recommend this to be set true, but -# it does mess with some (less popular) glyphs in a nasty way. -# -# The goal here is to increase the height of some fonts by 1 px -# but leave the x-height where it is. Arial is a good example -# of this working properly. Compare the heights of Arial, Times -# and Freesans with this on, vs. TT hinted versions of Arial and -# Times. -# -# -# Possible values: -# true - enable height adjustment -# false - do not enable height adjustment -# -# -# Default: false - -INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true - - -# Experimental emboldening values for OSX mode -INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE=0 -INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE=0 -INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE=0 -INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE=0 - -################################################################# -########################### EXAMPLES ############################ -################################################################# -# -# Make sure to set your style in /etc/fonts/local.conf too. -# -# Possible options: -# -# DEFAULT - Use above settings. A compromise that should please most people. -# OSX - Simulate OSX rendering -# UBUNTU - Simulate UBUNTU rendering -# LINUX - Generic "Linux" style - no snapping or certain other tweaks -# WINDOWS - Simulate Windows rendering -# WINDOWS7 - Simulate Windows rendering with normal glyphs -# WINDOWS7LIGHT- Simulate Windows 7 rendering with lighter glyphs -# WINDOWS - Simulate Windows rendering -# VANILLA - Just subpixel hinting -# CUSTOM - Your own choice. See below -# ----- Infinality styles ----- -# CLASSIC - Infinality rendering circa 2010. No snapping. -# NUDGE - CLASSIC with lightly stem snapping and tweaks -# PUSH - CLASSIC with medium stem snapping and tweaks -# SHOVE - Full stem snapping and tweaks without sharpening -# SHARPENED - Full stem snapping, tweaks, and Windows-style sharpening -# INFINALITY - Settings I use -# DISABLED - Act as though running without the extra infinality enhancements (just subpixel hinting). - -### NEEDS WORK ### -################# OSX STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="03 32 38 32 03" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=25 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="1000 80" -#INFINALITY_FT_BRIGHTNESS="10" -#INFINALITY_FT_CONTRAST="20" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false -#INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE=0 -#INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE=8 -#INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE=16 -#INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE=0 - - - - -################# UBUNTU STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="1000 80" -#INFINALITY_FT_BRIGHTNESS="-10" -#INFINALITY_FT_CONTRAST="15" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - - -################# LINUX STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - -################# WINDOWS XP STYLE LIGHT ################# - -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=15 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120" -#INFINALITY_FT_BRIGHTNESS="20" -#INFINALITY_FT_CONTRAST="30" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# WINDOWS 7 STYLE LIGHT ################# - -#INFINALITY_FT_FILTER_PARAMS="20 25 38 25 05" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=100 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="1000 160" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="20" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# WINDOWS XP STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=15 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120" -#INFINALITY_FT_BRIGHTNESS="10" -#INFINALITY_FT_CONTRAST="20" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# WINDOWS 7 STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="20 25 42 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120" -#INFINALITY_FT_BRIGHTNESS="10" -#INFINALITY_FT_CONTRAST="20" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -############### VANILLA STYLE ############## - -#INFINALITY_FT_FILTER_PARAMS="06 25 38 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - -############### CLASSIC INFINALITY STYLE ############## - -#INFINALITY_FT_FILTER_PARAMS="06 25 38 25 06" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - -################# NUDGE STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - -################# PUSH STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=75 -#INFINALITY_FT_STEM_FITTING_STRENGTH=50 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# INFINALITY STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=5 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25 -#INFINALITY_FT_STEM_FITTING_STRENGTH=25 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# SHOVE STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=100 -#INFINALITY_FT_STEM_FITTING_STRENGTH=100 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# SHARPENED INFINALITY STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25 -#INFINALITY_FT_STEM_FITTING_STRENGTH=25 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true - - - -################# DISABLED STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS= -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH= -#INFINALITY_FT_FRINGE_FILTER_STRENGTH= -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH= -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH= -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH= -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH= -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH= -#INFINALITY_FT_STEM_FITTING_STRENGTH= -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT= -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE= -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false - - - -################# CUSTOM STYLE ################# - -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11" -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=100 -#INFINALITY_FT_STEM_FITTING_STRENGTH=100 -#INFINALITY_FT_GAMMA_CORRECTION="0 100" -#INFINALITY_FT_BRIGHTNESS="0" -#INFINALITY_FT_CONTRAST="0" -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
\ No newline at end of file diff --git a/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild b/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild deleted file mode 100644 index 8d4d6e4..0000000 --- a/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 1999-2012 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI="4" - -DESCRIPTION="Configuration to be used in conjunction with the freetype-infinality subpixel hinting" -HOMEPAGE="http://www.infinality.net/blog/infinality-freetype-patches/" -SRC_URI="http://dev.gentoo.org/~yngwin/distfiles/${P}.tar.xz" - -LICENSE="MIT" -SLOT="0" -KEYWORDS="~amd64 ~x86" -IUSE="" - -DEPEND="" -RDEPEND="app-admin/eselect-fontconfig - app-admin/eselect-infinality - media-libs/freetype:2[lcdfilter] - >=x11-libs/libXft-2.3.0" - -src_configure() { - : -} - -src_compile() { - : -} - -src_install() { - dodoc infinality/{CHANGELOG,CHANGELOG.pre_git,README} - - insinto /etc/fonts/conf.avail - doins conf.avail/52-infinality.conf - - insinto /etc/fonts/infinality - doins -r infinality/{conf.src,styles.conf.avail,infinality.conf} - - insinto /etc/X11/ - doins "${FILESDIR}"/Xresources - - newenvd "${FILESDIR}"/infinality-settings.sh 99lcdfilter -} - -pkg_postinst() { - elog "Use eselect fontconfig enable 52-infinality.conf" - elog "to enable the configuration" -} diff --git a/media-libs/freetype/Manifest b/media-libs/freetype/Manifest deleted file mode 100644 index 164bf46..0000000 --- a/media-libs/freetype/Manifest +++ /dev/null @@ -1,9 +0,0 @@ -AUX freetype-2.3.2-enable-valid.patch 624 SHA256 3c26cd8b92510490b4bdbdd12b078e33a4f8607eaee64a800c3ea23097d5d43b SHA512 4dd637fa77b3386cc20fff3e68c64411fdc85a09b5bd61a75647aeff294e037c22cf0b788dae1e90f4cb12b1cb2775d0ac658c82eb998603b070af5f8242cff6 WHIRLPOOL 2c25610f0ecde1d5517c780d6db96abd00bbf04fda9343a3cb1ccaddf6b3263bfb6806d198db110566df1cfd765e1c734f6e303ab81a50e60ce7697ce506162e -AUX freetype-2.4.9-type1-incremental.patch 3213 SHA256 a41b8a606ab53ff84d96e6390514ed3ee3cba28d35f822c504169771525ef012 SHA512 ca877af277d8e95240020907ef874facf09b35f23c70218bd59285a9285a2c7bca72cad42a89e71648cd6fb0d44a6eb8c3ff76068bf0484c77126d7301621ad4 WHIRLPOOL 24bdfc8af7cfa021ae2e78920cb9c841d0fe830d79ad24088c25ce27e3d01160418b210b8dd82cc916be32f3e8971d8901793e430604a3ab576eda9816b96b32 -AUX freetype-add-subpixel-hinting-infinality.patch 118843 SHA256 4b7e1a9d9784ea57e9607d85c2a7dd5c16fc2bfc31a91498bae11653d4bfd5b2 SHA512 bcc0e933cd9604eaf9b4ac57f7d49db6517005f70a3d35cb5973de6d68364f53515a2150d126e12f0f79030357d451de304db77274a87d39ddbb54cf55e4ef11 WHIRLPOOL 80ff2a8b134edaef121940e2e017bdff8d7050e0ee13acf94ea12d162a04c981d0a468c6e9e6361a89d516e804d33eb9b6e46b2a9903bfe672df598cb3a4e025 -AUX freetype-enable-subpixel-hinting-infinality.patch 1226 SHA256 fc555a25c517e8fd0233e442ef25412150225ef4e800e7cd53494755b0086626 SHA512 1c87195a8b1b16805c98251e1379b96e3497064a4ef12935a579467c8f02c09913fcd422672132ee8a1d3e90ebc350057f988eb93be412515ca4a81c83f93b63 WHIRLPOOL 8465d448bf4df673d0123b5449b393ea4210e28c5ba522d731ea62edfab1acc1f2724e930e781d90bfdbcc2deefc1fac81a06a5f3720ecdc215e941b32d1732a -AUX freetype-entire-infinality-patchset.patch 172999 SHA256 f135d1c3a6e6ef348e78066bf83e0e4744cd86127dc541ae0246de191c1074bf SHA512 82d851c61aab8bbc90a29903c782db482e4fd8a4bb3f52b22877a83eda89da03c93019f1912e983130e2525803ec1723554a3e33d34d8ea8b9762c7a5d487a04 WHIRLPOOL 83310aed6d2dc1b192dcce80e9e47c93d2748e43caf86b375f18afda5a63220bd36c7653dd52939e6baf73e44a8fac95dea23cadc1c98d8b19b5e1f8818f9e32 -DIST freetype-2.4.10.tar.bz2 1508927 SHA256 0c8e242c33c45928de560d7d595db06feb41d1b22167e37260ceabe72f9e992f SHA512 41547dba00a949792b44f42a8b5a69fb6dd4c6f3d454221a0b20ac6eaedd938465922197ccdd49bdff4c03e85ab4d38a77d3c48a597e3c69790ebeba359a0107 WHIRLPOOL 455efafdc97677bec9ee234d3aedde0945123587a788e483bfeb9c1a1d00a121e2921632145678d439fbd497c96191b053143247fb31ed039ad5984d0be47eef -DIST freetype-doc-2.4.10.tar.bz2 106697 SHA256 b83b46fd02d00c256eea12bddf598454f95858dbeaa853b76dac5974f0321fd8 SHA512 feabab8f8589bce736b4aeb92513c3830cd0e95682f22e0c113c28a5c23c9732e5f6b7c309c5154570adfb87278b3bdfb8c9b34be309c383e63690745ae16e11 WHIRLPOOL 2f6ae792acd8435b7dec4359bc0a611a0bfffd26e46bf52d86be6f3f2ea113424267edcffaec833a9b96da0b462cd8328bef951708db18b4b8e54e3658d61352 -DIST ft2demos-2.4.10.tar.bz2 163949 SHA256 3fb7e97f35c0f59ecd967577a3e77fbcca10d84c00129a74e5da45bf3625cc45 SHA512 18fabb65776cc6fad164eff07413e41ea1887f38035bc3fe81f9c525160f718bd568592d81e259c49616ad167daefa591e6614f9049f51723716465a4dac8769 WHIRLPOOL 7bb4ce7fedf4176ff372c60d4ae5c9e84fcca28fd77ab5ae0a26248d0d45acd764c860e926d5dfca4053431ccbb60858c60f76b414b863b20d77e89f32e357e4 -EBUILD freetype-2.4.10-r1.ebuild 3630 SHA256 99168b729c21845b8a3a287df3f6ed8c431b8e40dc52f1fc839783904a68052e SHA512 2daf0b85762104d9e55958dc175d5d4c29f33737dc85d7dff208a1bf7a0dce9ec29941943f67c0f309a392eff66a422f1717de0cfc0223d35dbdf25c4bee6431 WHIRLPOOL c52b21a77ddcfff842b8fac979e7b40efc49478f67dc59fd708afb17935dcc7b9504f701993db7b2ae1e496fb8a95c618355ddcb0744df7816af177939046646 diff --git a/media-libs/freetype/files/freetype-2.3.2-enable-valid.patch b/media-libs/freetype/files/freetype-2.3.2-enable-valid.patch deleted file mode 100644 index 44f3bf6..0000000 --- a/media-libs/freetype/files/freetype-2.3.2-enable-valid.patch +++ /dev/null @@ -1,22 +0,0 @@ -Enables gxvalid and otvalid modules for use with ftvalid. - ---- freetype-2.2.1/modules.cfg.orig 2006-07-07 21:01:09.000000000 -0400 -+++ freetype-2.2.1/modules.cfg 2006-07-07 21:01:54.000000000 -0400 -@@ -110,7 +110,7 @@ - AUX_MODULES += cache - - # TrueType GX/AAT table validation. Needs ftgxval.c below. --# AUX_MODULES += gxvalid -+AUX_MODULES += gxvalid - - # Support for streams compressed with gzip (files with suffix .gz). - # -@@ -124,7 +124,7 @@ - - # OpenType table validation. Needs ftotval.c below. - # --# AUX_MODULES += otvalid -+AUX_MODULES += otvalid - - # Auxiliary PostScript driver component to share common code. - # diff --git a/media-libs/freetype/files/freetype-2.4.9-type1-incremental.patch b/media-libs/freetype/files/freetype-2.4.9-type1-incremental.patch deleted file mode 100644 index a08c44d..0000000 --- a/media-libs/freetype/files/freetype-2.4.9-type1-incremental.patch +++ /dev/null @@ -1,101 +0,0 @@ ---- a/src/type1/t1load.c -+++ b/src/type1/t1load.c -@@ -71,6 +71,13 @@ - #include "t1errors.h" - - -+#ifdef FT_CONFIG_OPTION_INCREMENTAL -+#define IS_INCREMENTAL ( face->root.internal->incremental_interface != 0 ) -+#else -+#define IS_INCREMENTAL 0 -+#endif -+ -+ - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ -@@ -1030,7 +1037,8 @@ - static int - read_binary_data( T1_Parser parser, - FT_Long* size, -- FT_Byte** base ) -+ FT_Byte** base, -+ FT_Bool incremental ) - { - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; -@@ -1065,8 +1073,12 @@ - } - } - -- FT_ERROR(( "read_binary_data: invalid size field\n" )); -- parser->root.error = T1_Err_Invalid_File_Format; -+ if( !incremental ) -+ { -+ FT_ERROR(( "read_binary_data: invalid size field\n" )); -+ parser->root.error = T1_Err_Invalid_File_Format; -+ } -+ - return 0; - } - -@@ -1387,16 +1399,17 @@ - FT_Byte* base; - - -- /* If the next token isn't `dup' we are done. */ -- if ( parser->root.cursor + 4 < parser->root.limit && -- ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) -+ /* If we are out of data, or if the next token isn't `dup', */ -+ /* we are done. */ -+ if ( parser->root.cursor + 4 >= parser->root.limit || -+ ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) - break; - - T1_Skip_PS_Token( parser ); /* `dup' */ - - idx = T1_ToInt( parser ); - -- if ( !read_binary_data( parser, &size, &base ) ) -+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) - return; - - /* The binary string is followed by one token, e.g. `NP' */ -@@ -1582,7 +1595,7 @@ - cur++; /* skip `/' */ - len = parser->root.cursor - cur; - -- if ( !read_binary_data( parser, &size, &base ) ) -+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) ) - return; - - /* for some non-standard fonts like `Optima' which provides */ -@@ -1871,7 +1884,7 @@ - - - parser->root.cursor = start_binary; -- if ( !read_binary_data( parser, &s, &b ) ) -+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) - return T1_Err_Invalid_File_Format; - have_integer = 0; - } -@@ -1884,7 +1897,7 @@ - - - parser->root.cursor = start_binary; -- if ( !read_binary_data( parser, &s, &b ) ) -+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) ) - return T1_Err_Invalid_File_Format; - have_integer = 0; - } -@@ -2160,9 +2173,7 @@ - type1->subrs_len = loader.subrs.lengths; - } - --#ifdef FT_CONFIG_OPTION_INCREMENTAL -- if ( !face->root.internal->incremental_interface ) --#endif -+ if ( !IS_INCREMENTAL ) - if ( !loader.charstrings.init ) - { - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" )); diff --git a/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch b/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch deleted file mode 100644 index 8bb026b..0000000 --- a/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch +++ /dev/null @@ -1,2927 +0,0 @@ -diff -Nur freetype-orig/devel/ftoption.h freetype-subpixel/devel/ftoption.h ---- freetype-orig/devel/ftoption.h 2012-06-14 00:35:57.000000000 -0500 -+++ freetype-subpixel/devel/ftoption.h 2012-06-15 07:31:12.119986648 -0500 -@@ -560,6 +560,28 @@ - - /*************************************************************************/ - /* */ -+ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ -+ /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ -+ /* replaces the native TrueType hinting mechanism when anything but */ -+ /* FT_RENDER_MODE_MONO is requested. */ -+ /* */ -+ /* Enabling this causes the TrueType driver to ignore instructions under */ -+ /* certain conditions. This is done in accordance with the guide here, */ -+ /* with some minor differences: */ -+ /* */ -+ /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ -+ /* */ -+ /* By undefining this, you only compile the code necessary to hint */ -+ /* TrueType glyphs with native TT hinting. */ -+ /* */ -+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ -+ /* defined. */ -+ /* */ -+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ -+ -+ /*************************************************************************/ -+ /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ -diff -Nur freetype-orig/include/freetype/config/ftoption.h freetype-subpixel/include/freetype/config/ftoption.h ---- freetype-orig/include/freetype/config/ftoption.h 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500 -@@ -560,6 +560,28 @@ - - /*************************************************************************/ - /* */ -+ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ -+ /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ -+ /* replaces the native TrueType hinting mechanism when anything but */ -+ /* FT_RENDER_MODE_MONO is requested. */ -+ /* */ -+ /* Enabling this causes the TrueType driver to ignore instructions under */ -+ /* certain conditions. This is done in accordance with the guide here, */ -+ /* with some minor differences: */ -+ /* */ -+ /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ -+ /* */ -+ /* By undefining this, you only compile the code necessary to hint */ -+ /* TrueType glyphs with native TT hinting. */ -+ /* */ -+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ -+ /* defined. */ -+ /* */ -+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ -+ -+ /*************************************************************************/ -+ /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ -diff -Nur freetype-orig/include/freetype/internal/ftobjs.h freetype-subpixel/include/freetype/internal/ftobjs.h ---- freetype-orig/include/freetype/internal/ftobjs.h 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/include/freetype/internal/ftobjs.h 2012-06-15 07:31:12.147985698 -0500 -@@ -81,6 +81,14 @@ - #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) - #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) - -+ /* -+ * These are used in ttinterp.c for subpixel hinting with an -+ * adjustable grids-per-pixel value. -+ */ -+#define FT_PIX_FLOOR_GRID( x, n ) ( (x) & ~( 64 / (n) - 1 ) ) -+#define FT_PIX_ROUND_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 32 / (n), (n) ) -+#define FT_PIX_CEIL_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 63 / (n), (n) ) -+ - - /* - * Return the highest power of 2 that is <= value; this correspond to -diff -Nur freetype-orig/src/truetype/rules.mk freetype-subpixel/src/truetype/rules.mk ---- freetype-orig/src/truetype/rules.mk 2011-01-03 00:06:51.000000000 -0600 -+++ freetype-subpixel/src/truetype/rules.mk 2012-06-15 07:31:12.148985665 -0500 -@@ -31,7 +31,8 @@ - $(TT_DIR)/ttinterp.c \ - $(TT_DIR)/ttobjs.c \ - $(TT_DIR)/ttpic.c \ -- $(TT_DIR)/ttpload.c -+ $(TT_DIR)/ttpload.c \ -+ $(TT_DIR)/ttsubpix.c - - # TrueType driver headers - # -diff -Nur freetype-orig/src/truetype/truetype.c freetype-subpixel/src/truetype/truetype.c ---- freetype-orig/src/truetype/truetype.c 2009-07-03 08:28:24.000000000 -0500 -+++ freetype-subpixel/src/truetype/truetype.c 2012-06-15 07:31:12.149985631 -0500 -@@ -27,6 +27,7 @@ - - #ifdef TT_USE_BYTECODE_INTERPRETER - #include "ttinterp.c" -+#include "ttsubpix.c" - #endif - - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -diff -Nur freetype-orig/src/truetype/ttgload.c freetype-subpixel/src/truetype/ttgload.c ---- freetype-orig/src/truetype/ttgload.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/src/truetype/ttgload.c 2012-06-15 07:31:12.151985563 -0500 -@@ -32,6 +32,7 @@ - #endif - - #include "tterrors.h" -+#include "ttsubpix.h" - - - /*************************************************************************/ -@@ -149,6 +150,15 @@ - loader->top_bearing = top_bearing; - loader->vadvance = advance_height; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( loader->exec ) -+ loader->exec->sph_tweak_flags = 0; -+ -+ /* this may not be the right place for this, but it works */ -+ if ( loader->exec && loader->exec->ignore_x_mode ) -+ sph_set_tweaks( loader, glyph_index ); -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - if ( !loader->linear_def ) - { - loader->linear_def = 1; -@@ -813,6 +823,13 @@ - loader->pp4 = zone->cur[zone->n_points - 1]; - } - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) -+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); -+ -+ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) -+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); -+#endif - return TT_Err_Ok; - } - -@@ -835,6 +852,13 @@ - FT_Outline* outline; - FT_Int n_points; - -+ TT_Face face = (TT_Face)loader->face; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_String* family = face->root.family_name; -+ int ppem = loader->size->metrics.x_ppem; -+ FT_String* style = face->root.style_name; -+ float x_scale_factor = 1.0; -+#endif - - outline = &gloader->current.outline; - n_points = outline->n_points; -@@ -889,6 +913,26 @@ - loader->zone.n_points + 4 ); - } - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* scale, but only if enabled and only if TT hinting is being used */ -+ if ( IS_HINTED( loader->load_flags ) ) -+ x_scale_factor = scale_test_tweak( face, family, ppem, style, -+ loader->glyph_index, X_SCALING_Rules, -+ X_SCALING_RULES_SIZE ); -+ /* scale the glyph */ -+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || -+ x_scale_factor != 1.0 ) -+ { -+ FT_Vector* vec = outline->points; -+ FT_Vector* limit = outline->points + n_points; -+ FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale * x_scale_factor; -+ FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; -+ -+ /* compensate for any scaling by de/emboldening */ -+ if ( x_scale_factor != 1.0 && ppem > 11 ) -+ FT_Outline_EmboldenXY( outline, -+ (FT_Int) ( 16.0 * (float)ppem * ( 1.0 - x_scale_factor) ), 0 ); -+#else - /* scale the glyph */ - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { -@@ -896,7 +940,7 @@ - FT_Vector* limit = outline->points + n_points; - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; -- -+#endif - - for ( ; vec < limit; vec++ ) - { -@@ -1648,12 +1692,26 @@ - { - FT_Byte* widthp; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Bool ignore_x_mode; -+ -+ -+ ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != -+ FT_RENDER_MODE_MONO ); -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, - glyph_index ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( widthp && -+ ( ( ignore_x_mode && loader->exec->compatible_widths ) || -+ !ignore_x_mode || -+ SPH_OPTION_BITMAP_WIDTHS ) ) -+#else - if ( widthp ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - glyph->metrics.horiAdvance = *widthp << 6; - } - -@@ -1848,6 +1906,15 @@ - { - TT_ExecContext exec; - FT_Bool grayscale; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Bool subpixel_hinting; -+ FT_Bool grayscale_hinting; -+#if 0 -+ FT_Bool compatible_widths; -+ FT_Bool symmetrical_smoothing; -+ FT_Bool bgr; -+#endif -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - if ( !size->cvt_ready ) -@@ -1865,11 +1932,88 @@ - if ( !exec ) - return TT_Err_Could_Not_Find_Context; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+ subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) -+ != FT_RENDER_MODE_MONO ) && -+ SPH_OPTION_SET_SUBPIXEL ); -+ -+ if ( subpixel_hinting ) -+ grayscale = grayscale_hinting = FALSE; -+ -+ else if ( SPH_OPTION_SET_GRAYSCALE ) -+ { -+ grayscale = grayscale_hinting = TRUE; -+ subpixel_hinting = FALSE; -+ } -+ -+ if ( FT_IS_TRICKY( glyph->face ) ) -+ { -+ subpixel_hinting = grayscale_hinting = FALSE; -+ } -+ -+ exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; -+ exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; -+ if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) -+ exec->rasterizer_version = 35; -+ -+#if 1 -+ exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; -+ exec->symmetrical_smoothing = FALSE; -+ exec->bgr = FALSE; -+#else /* 0 */ -+ exec->compatible_widths = -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != -+ TT_LOAD_COMPATIBLE_WIDTHS ); -+ exec->symmetrical_smoothing = -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != -+ TT_LOAD_SYMMETRICAL_SMOOTHING ); -+ exec->bgr = -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != -+ TT_LOAD_BGR ); -+#endif /* 0 */ -+ -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - grayscale = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); - -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - TT_Load_Context( exec, face, size ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+ /* a change from mono to subpixel rendering (and vice versa) */ -+ /* requires a re-execution of the CVT program */ -+ if ( subpixel_hinting != exec->subpixel_hinting ) -+ { -+ FT_UInt i; -+ -+ -+ exec->subpixel_hinting = subpixel_hinting; -+ -+ for ( i = 0; i < size->cvt_size; i++ ) -+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); -+ tt_size_run_prep( size, pedantic ); -+ } -+ -+ /* a change from mono to grayscale rendering (and vice versa) */ -+ /* requires a re-execution of the CVT program */ -+ if ( grayscale != exec->grayscale_hinting ) -+ { -+ FT_UInt i; -+ -+ -+ exec->grayscale_hinting = grayscale_hinting; -+ -+ for ( i = 0; i < size->cvt_size; i++ ) -+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); -+ tt_size_run_prep( size, pedantic ); -+ } -+ -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* a change from mono to grayscale rendering (and vice versa) */ - /* requires a re-execution of the CVT program */ - if ( grayscale != exec->grayscale ) -@@ -1887,6 +2031,8 @@ - tt_size_run_prep( size, pedantic ); - } - -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* see whether the cvt program has disabled hinting */ - if ( exec->GS.instruct_control & 1 ) - load_flags |= FT_LOAD_NO_HINTING; -diff -Nur freetype-orig/src/truetype/ttinterp.c freetype-subpixel/src/truetype/ttinterp.c ---- freetype-orig/src/truetype/ttinterp.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/src/truetype/ttinterp.c 2012-06-16 10:31:47.161209856 -0500 -@@ -27,13 +27,16 @@ - #include FT_SYSTEM_H - - #include "ttinterp.h" -- - #include "tterrors.h" -+#include "ttsubpix.h" - - - #ifdef TT_USE_BYTECODE_INTERPRETER - - -+#define xxxSPH_DEBUG -+#define xxxSPH_DEBUG_MORE_VERBOSE -+ - #define TT_MULFIX FT_MulFix - #define TT_MULDIV FT_MulDiv - #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round -@@ -153,11 +156,11 @@ - #define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - --#define SET_SuperRound( scale, flags ) \ -- SetSuperRound( EXEC_ARG_ scale, flags ) -+#define SET_SuperRound( scale, flags, res ) \ -+ SetSuperRound( EXEC_ARG_ scale, flags, res ) - --#define ROUND_None( d, c ) \ -- Round_None( EXEC_ARG_ d, c ) -+#define ROUND_None( d, c, e ) \ -+ Round_None( EXEC_ARG_ d, c, e ) - - #define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) -@@ -168,8 +171,8 @@ - #define CUR_Func_move_orig( z, p, d ) \ - CUR.func_move_orig( EXEC_ARG_ z, p, d ) - --#define CUR_Func_round( d, c ) \ -- CUR.func_round( EXEC_ARG_ d, c ) -+#define CUR_Func_round( d, c, e ) \ -+ CUR.func_round( EXEC_ARG_ d, c, e ) - - #define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) -@@ -1850,6 +1853,10 @@ - - if ( v != 0 ) - { -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( !CUR.ignore_x_mode || -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += TT_MULDIV( distance, - v * 0x10000L, - CUR.F_dot_P ); -@@ -1932,6 +1939,10 @@ - { - FT_UNUSED_EXEC; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( !CUR.ignore_x_mode || -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVEX ) ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; - } -@@ -1994,6 +2005,8 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* The compensated distance. */ - /* */ -@@ -2005,11 +2018,13 @@ - /* */ - static FT_F26Dot6 - Round_None( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; -+ FT_UNUSED( resolution ); - - - if ( distance >= 0 ) -@@ -2024,6 +2039,7 @@ - if ( val > 0 ) - val = 0; - } -+ - return val; - } - -@@ -2041,12 +2057,15 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -@@ -2055,15 +2074,15 @@ - - if ( distance >= 0 ) - { -- val = distance + compensation + 32; -+ val = distance + compensation + 32 / resolution; - if ( distance && val > 0 ) -- val &= ~63; -+ val &= ~( 64 / resolution - 1 ); - else - val = 0; - } - else - { -- val = -FT_PIX_ROUND( compensation - distance ); -+ val = -FT_PIX_ROUND_GRID( compensation - distance, resolution ); - if ( val > 0 ) - val = 0; - } -@@ -2085,12 +2104,15 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -@@ -2099,13 +2121,15 @@ - - if ( distance >= 0 ) - { -- val = FT_PIX_FLOOR( distance + compensation ) + 32; -+ val = FT_PIX_FLOOR_GRID( distance + compensation, resolution ) + -+ 32 / resolution; - if ( distance && val < 0 ) - val = 0; - } - else - { -- val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); -+ val = -( FT_PIX_FLOOR_GRID( compensation - distance, resolution ) + -+ 32 / resolution ); - if ( val > 0 ) - val = 0; - } -@@ -2127,12 +2151,15 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -@@ -2143,13 +2170,13 @@ - { - val = distance + compensation; - if ( distance && val > 0 ) -- val &= ~63; -+ val &= ~( 64 / resolution - 1 ); - else - val = 0; - } - else - { -- val = -( ( compensation - distance ) & -64 ); -+ val = -( ( compensation - distance ) & -( 64 / resolution ) ); - if ( val > 0 ) - val = 0; - } -@@ -2171,12 +2198,15 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -@@ -2185,15 +2215,15 @@ - - if ( distance >= 0 ) - { -- val = distance + compensation + 63; -+ val = distance + compensation + ( 64 / resolution - 1 ); - if ( distance && val > 0 ) -- val &= ~63; -+ val &= ~( 64 / resolution - 1 ); - else - val = 0; - } - else - { -- val = - FT_PIX_CEIL( compensation - distance ); -+ val = -FT_PIX_CEIL_GRID( compensation - distance, resolution ); - if ( val > 0 ) - val = 0; - } -@@ -2215,12 +2245,15 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ - static FT_F26Dot6 - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -@@ -2229,15 +2262,15 @@ - - if ( distance >= 0 ) - { -- val = distance + compensation + 16; -+ val = distance + compensation + 16 / resolution; - if ( distance && val > 0 ) -- val &= ~31; -+ val &= ~( 32 / resolution - 1 ); - else - val = 0; - } - else - { -- val = -FT_PAD_ROUND( compensation - distance, 32 ); -+ val = -FT_PAD_ROUND( compensation - distance, 32 / resolution ); - if ( val > 0 ) - val = 0; - } -@@ -2259,6 +2292,8 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ -@@ -2270,10 +2305,13 @@ - /* */ - static FT_F26Dot6 - Round_Super( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -+ FT_UNUSED( resolution ); -+ - - if ( distance >= 0 ) - { -@@ -2309,6 +2347,8 @@ - /* */ - /* compensation :: The engine compensation. */ - /* */ -+ /* resolution :: The number of grid lines per pixel. */ -+ /* */ - /* <Return> */ - /* Rounded distance. */ - /* */ -@@ -2318,10 +2358,13 @@ - /* */ - static FT_F26Dot6 - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ) -+ FT_F26Dot6 compensation, -+ FT_Int resolution ) - { - FT_F26Dot6 val; - -+ FT_UNUSED( resolution ); -+ - - if ( distance >= 0 ) - { -@@ -2404,13 +2447,19 @@ - /* Sets Super Round parameters. */ - /* */ - /* <Input> */ -- /* GridPeriod :: Grid period */ -- /* selector :: SROUND opcode */ -+ /* GridPeriod :: The grid period. */ -+ /* */ -+ /* selector :: The SROUND opcode. */ -+ /* */ -+ /* resolution :: The number of grid lines per pixel. */ - /* */ - static void - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, -- FT_Long selector ) -+ FT_Long selector, -+ FT_Int resolution ) - { -+ FT_UNUSED( resolution ); -+ - switch ( (FT_Int)( selector & 0xC0 ) ) - { - case 0: -@@ -3080,13 +3129,13 @@ - - - #define DO_SROUND \ -- SET_SuperRound( 0x4000, args[0] ); \ -+ SET_SuperRound( 0x4000, args[0], 1 ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - - #define DO_S45ROUND \ -- SET_SuperRound( 0x2D41, args[0] ); \ -+ SET_SuperRound( 0x2D41, args[0], 1 ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; - -@@ -3257,12 +3306,12 @@ - args[0] = ( args[0] != args[1] ); - - --#define DO_ODD \ -- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); -+#define DO_ODD \ -+ args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 64 ); - - --#define DO_EVEN \ -- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); -+#define DO_EVEN \ -+ args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 0 ); - - - #define DO_AND \ -@@ -3311,6 +3360,34 @@ - #define DO_CEILING \ - args[0] = FT_PIX_CEIL( args[0] ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+#define DO_RS \ -+ { \ -+ FT_ULong I = (FT_ULong)args[0]; \ -+ \ -+ \ -+ if ( BOUNDSL( I, CUR.storeSize ) ) \ -+ { \ -+ if ( CUR.pedantic_hinting ) \ -+ ARRAY_BOUND_ERROR; \ -+ else \ -+ args[0] = 0; \ -+ } \ -+ else \ -+ { \ -+ /* subpixel hinting - avoid Typeman Dstroke and */ \ -+ /* IStroke and Vacuform rounds */ \ -+ \ -+ if ( CUR.compatibility_mode && \ -+ ( I == 24 || I == 22 || I == 8 ) ) \ -+ args[0] = 0; \ -+ else \ -+ args[0] = CUR.storage[I]; \ -+ } \ -+ } -+ -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - #define DO_RS \ - { \ -@@ -3330,6 +3407,8 @@ - args[0] = CUR.storage[I]; \ - } - -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - - #define DO_WS \ - { \ -@@ -3405,15 +3484,17 @@ - CUR.error = TT_Err_Debug_OpCode; - - --#define DO_ROUND \ -- args[0] = CUR_Func_round( \ -- args[0], \ -- CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); -+#define DO_ROUND \ -+ args[0] = CUR_Func_round( \ -+ args[0], \ -+ CUR.tt_metrics.compensations[CUR.opcode - 0x68], \ -+ 1 ); - - --#define DO_NROUND \ -- args[0] = ROUND_None( args[0], \ -- CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); -+#define DO_NROUND \ -+ args[0] = ROUND_None( args[0], \ -+ CUR.tt_metrics.compensations[CUR.opcode - 0x6C], \ -+ 1 ); - - - #define DO_MAX \ -@@ -4587,6 +4668,24 @@ - TT_DefRecord* rec; - TT_DefRecord* limit; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+#if 0 -+ int opcode_pattern[4][12] = { -+ /* VacuFormRound function */ -+ {0x45,0x23,0x46,0x60,0x20}, -+ /* inline delta function 1 */ -+ {0x4B,0x53,0x23,0x4B,0x51,0x5A,0x58,0x38,0x1B,0x21,0x21,0x59}, -+ /* inline delta function 2 */ -+ {0x4B,0x54,0x58,0x38,0x1B,0x5A,0x21,0x21,0x59}, -+ /* diagonal stroke function */ -+ {0x20,0x20,0x40,0x60,0x47,0x40,0x23,0x42}, -+ }; -+ int opcode_patterns = 4; -+ int i; -+ int opcode_pointer[4] = {0,0,0,0}; -+#endif -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - - /* some font programs are broken enough to redefine functions! */ - /* We will then parse the current table. */ -@@ -4620,10 +4719,11 @@ - return; - } - -- rec->range = CUR.curRange; -- rec->opc = (FT_UInt16)n; -- rec->start = CUR.IP + 1; -- rec->active = TRUE; -+ rec->range = CUR.curRange; -+ rec->opc = (FT_UInt16)n; -+ rec->start = CUR.IP + 1; -+ rec->active = TRUE; -+ rec->inline_delta = FALSE; - - if ( n > CUR.maxFunc ) - CUR.maxFunc = (FT_UInt16)n; -@@ -4633,6 +4733,78 @@ - - while ( SKIP_Code() == SUCCESS ) - { -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+#if 0 -+#ifdef SPH_DEBUG_MORE_VERBOSE -+ printf ("Opcode: %d ", CUR.opcode); -+#endif -+ -+ for ( i = 0; i < opcode_patterns; i++ ) -+ { -+ if ( CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) -+ { -+#ifdef SPH_DEBUG_MORE_VERBOSE -+ printf( "function %d, opcode ptrn: %d" -+ " op# %d: %d FOUND \n", -+ n, i, opcode_pointer[i], CUR.opcode ); -+#endif -+ opcode_pointer[i] += 1; -+ -+ if ( i == 0 && opcode_pointer[0] == 5 ) -+ { -+ -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; -+ CUR.num_delta_funcs++; -+#ifdef SPH_DEBUG -+ printf( "Vacuform Round FUNCTION %d detected\n", n); -+#endif -+ /*rec->active = FALSE;*/ -+ opcode_pointer[i] = 0; -+ } -+ -+ if ( i == 1 && opcode_pointer[1] == 12 ) -+ { -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; -+ CUR.num_delta_funcs++; -+#ifdef SPH_DEBUG -+ printf( "inline delta FUNCTION1 %d detected\n", -+ n, CUR.num_delta_funcs); -+#endif -+ rec->inline_delta = TRUE; -+ opcode_pointer[i] = 0; -+ } -+ -+ if ( i == 2 && opcode_pointer[1] == 9 ) -+ { -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; -+ CUR.num_delta_funcs++; -+ rec->inline_delta = TRUE; -+#ifdef SPH_DEBUG -+ printf( "inline delta2 FUNCTION2 %d detected\n", -+ n, CUR.num_delta_funcs); -+#endif -+ opcode_pointer[i] = 0; -+ } -+ -+ if ( i == 4 && opcode_pointer[1] == 8 ) -+ { -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n; -+ CUR.num_delta_funcs++; -+ /*rec->active = FALSE;*/ -+#ifdef SPH_DEBUG -+ printf( "diagonal stroke function %d detected\n", -+ n, CUR.num_delta_funcs); -+#endif -+ opcode_pointer[i] = 0; -+ } -+ } -+ -+ else -+ opcode_pointer[i] = 0; -+ } -+#endif -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ -@@ -4676,6 +4848,15 @@ - - CUR.step_ins = FALSE; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* -+ * CUR.ignore_x_mode may be turned off prior to function calls. This -+ * ensures it is turned back on. -+ */ -+ CUR.ignore_x_mode = ( CUR.subpixel_hinting || CUR.grayscale_hinting ) -+ && !( CUR.sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ); -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - if ( pRec->Cur_Count > 0 ) - { - CUR.callTop++; -@@ -4709,6 +4890,10 @@ - TT_CallRec* pCrec; - TT_DefRecord* def; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Bool oldF; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - - /* first of all, check the index */ - -@@ -4746,6 +4931,20 @@ - if ( !def->active ) - goto Fail; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* This is test code used to detect inline delta functions */ -+ oldF = def->inline_delta; -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( def->inline_delta ) -+ CUR.in_delta_function = TRUE; -+ } -+ -+#ifdef SPH_DEBUG -+ printf("Entering function %d\n", F); -+#endif -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) - { -@@ -4767,6 +4966,13 @@ - def->start ); - - CUR.step_ins = FALSE; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ CUR.in_delta_function = oldF; -+ -+#ifdef SPH_DEBUG -+ printf("Leaving function %d\n", F); -+#endif -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - return; - - Fail: -@@ -4787,6 +4993,10 @@ - TT_CallRec* pCrec; - TT_DefRecord* def; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Bool oldF; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - - /* first of all, check the index */ - F = args[1]; -@@ -4823,6 +5033,15 @@ - if ( !def->active ) - goto Fail; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ oldF = def->inline_delta; -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( def->inline_delta ) -+ CUR.in_delta_function = TRUE; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { -@@ -4846,6 +5065,11 @@ - - CUR.step_ins = FALSE; - } -+ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ CUR.in_delta_function = oldF; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - return; - - Fail: -@@ -5195,6 +5419,12 @@ - } - } - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ -+ if ( CUR.ignore_x_mode && FT_ABS( D ) == 64 ) -+ D += 1; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - args[0] = D; - } - -@@ -5691,7 +5921,12 @@ - - if ( CUR.GS.freeVector.x != 0 ) - { -- CUR.zp2.cur[point].x += dx; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( !CUR.ignore_x_mode || -+ ( CUR.ignore_x_mode && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_MOVE_ZP2 ) ) ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } -@@ -5872,6 +6107,9 @@ - { - FT_F26Dot6 dx, dy; - FT_UShort point; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Int B1, B2; -+#endif - - - if ( CUR.top < CUR.GS.loop + 1 ) -@@ -5917,7 +6155,77 @@ - } - } - else -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ { -+ /* If not using ignore_x_mode rendering, allow ZP2 move. */ -+ /* If inline deltas aren't allowed, skip ZP2 move. */ -+ /* If using ignore_x_mode rendering, allow ZP2 point move if: */ -+ /* - freedom vector is y and compatibility_mode is off */ -+ /* - the glyph is composite and the move is in the Y direction */ -+ /* - the glyph is specifically set to allow SHPIX moves */ -+ /* - the move is on a previously Y-touched point */ -+ -+ if ( CUR.ignore_x_mode ) -+ { -+ /* save point for later comparison */ -+ if ( CUR.GS.freeVector.y != 0 ) -+ B1 = CUR.zp2.cur[point].y; -+ else -+ B1 = CUR.zp2.cur[point].x; -+ -+ if ( CUR.GS.freeVector.y != 0 && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_INLINE_DELTAS ) ) -+ goto Skip; -+ -+ if ( CUR.ignore_x_mode && -+ !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 ) -+ MOVE_Zp2_Point( point, dx, dy, TRUE ); -+ -+ else if ( CUR.ignore_x_mode && CUR.compatibility_mode ) -+ { -+ if ( CUR.ignore_x_mode && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) -+ { -+ dx = FT_PIX_ROUND ( B1 + dx ) - B1; -+ dy = FT_PIX_ROUND ( B1 + dy ) - B1; -+ } -+ -+ if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && -+ ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || -+ ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || -+ ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) -+ ) -+ MOVE_Zp2_Point( point, dx, dy, TRUE ); -+ } -+ -+ /* save new point */ -+ if ( CUR.GS.freeVector.y != 0 ) -+ B2 = CUR.zp2.cur[point].y; -+ else B2 = CUR.zp2.cur[point].x; -+ -+ /* reverse any disallowed moves */ -+ if ( ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && -+ CUR.GS.freeVector.y != 0 && -+ B1 % 64 != 0 && -+ B2 % 64 != 0 && B1 != B2 ) || -+ ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && -+ CUR.GS.freeVector.y != 0 && -+ B1 % 64 == 0 && -+ B2 % 64 != 0 && B1 != B2 ) ) -+ { -+#ifdef SPH_DEBUG -+ printf( "Reversing ZP2 move\n" ); -+#endif -+ MOVE_Zp2_Point( point, -dx, -dy, TRUE ); -+ } -+ } -+ else -+ MOVE_Zp2_Point( point, dx, dy, TRUE ); -+ } -+ Skip: -+#else - MOVE_Zp2_Point( point, dx, dy, TRUE ); -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - CUR.GS.loop--; - } -@@ -5939,7 +6247,18 @@ - { - FT_UShort point; - FT_F26Dot6 distance; -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Int gridlines_per_pixel = 1; -+ - -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.x != 0 ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; -+ else if ( CUR.GS.freeVector.y != 0 ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - point = (FT_UShort)args[0]; - -@@ -5963,6 +6282,15 @@ - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* subpixel hinting - make MSIRP respect CVT cut-in; */ -+ if ( CUR.ignore_x_mode && -+ CUR.GS.freeVector.x != 0 && -+ FT_ABS( distance - args[1] ) >= -+ CUR.GS.control_value_cutin / gridlines_per_pixel ) -+ distance = args[1]; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); - - CUR.GS.rp1 = CUR.GS.rp0; -@@ -5985,7 +6313,21 @@ - FT_UShort point; - FT_F26Dot6 cur_dist, - distance; -+ FT_Int gridlines_per_pixel = 1; -+ - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.x != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; -+ -+ else if ( CUR.GS.freeVector.y != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - point = (FT_UShort)args[0]; - -@@ -6000,7 +6342,8 @@ - { - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); - distance = CUR_Func_round( cur_dist, -- CUR.tt_metrics.compensations[0] ) - cur_dist; -+ CUR.tt_metrics.compensations[0], -+ gridlines_per_pixel ) - cur_dist; - } - else - distance = 0; -@@ -6025,8 +6368,22 @@ - FT_UShort point; - FT_F26Dot6 distance, - org_dist; -+ FT_Int gridlines_per_pixel = 1; - - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.x != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; -+ -+ else if ( CUR.GS.freeVector.y != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - cvtEntry = (FT_ULong)args[1]; - point = (FT_UShort)args[0]; - -@@ -6062,21 +6419,34 @@ - - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ - { -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* only adjust legacy fonts x otherwise breaks Calibri italic */ -+ if ( CUR.compatibility_mode ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.x ); - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, - CUR.GS.freeVector.y ), - CUR.zp0.cur[point] = CUR.zp0.org[point]; - } -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( distance > 0 && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && -+ CUR.GS.freeVector.y != 0 ) -+ distance = 0 ; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); - - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ - { -- if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) -+ if ( FT_ABS( distance - org_dist ) > -+ CUR.GS.control_value_cutin / gridlines_per_pixel ) - distance = org_dist; - -- distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); -+ distance = CUR_Func_round( distance, -+ CUR.tt_metrics.compensations[0], -+ gridlines_per_pixel ); - } - - CUR_Func_move( &CUR.zp0, point, distance - org_dist ); -@@ -6098,6 +6468,24 @@ - { - FT_UShort point; - FT_F26Dot6 org_dist, distance; -+ FT_Int minimum_distance_factor = 64; -+ FT_Int gridlines_per_pixel = 1; -+ -+ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.x != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ { -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; -+ minimum_distance_factor = 64 - gridlines_per_pixel / 3; -+ } -+ else if ( CUR.GS.freeVector.y != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - point = (FT_UShort)args[0]; -@@ -6163,11 +6551,13 @@ - if ( ( CUR.opcode & 4 ) != 0 ) - distance = CUR_Func_round( - org_dist, -- CUR.tt_metrics.compensations[CUR.opcode & 3] ); -+ CUR.tt_metrics.compensations[CUR.opcode & 3], -+ gridlines_per_pixel ); - else - distance = ROUND_None( - org_dist, -- CUR.tt_metrics.compensations[CUR.opcode & 3] ); -+ CUR.tt_metrics.compensations[CUR.opcode & 3], -+ gridlines_per_pixel ); - - /* minimum distance flag */ - -@@ -6175,13 +6565,17 @@ - { - if ( org_dist >= 0 ) - { -- if ( distance < CUR.GS.minimum_distance ) -- distance = CUR.GS.minimum_distance; -+ if ( distance < FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ) ) -+ distance = FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ); - } - else - { -- if ( distance > -CUR.GS.minimum_distance ) -- distance = -CUR.GS.minimum_distance; -+ if ( distance > -FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ) ) -+ distance = -FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ); - } - } - -@@ -6218,10 +6612,37 @@ - cur_dist, - org_dist; - -+ FT_Int minimum_distance_factor = 64; -+ FT_Int gridlines_per_pixel = 1; -+ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_Int B1; -+ FT_Int B2; -+ FT_Bool reverse_move = FALSE; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - point = (FT_UShort)args[0]; - cvtEntry = (FT_ULong)( args[1] + 1 ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.x != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ { -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X; -+ /* high value emboldens glyphs at lower ppems (< 14); */ -+ /* Courier looks better with 52 -- */ -+ /* MS ClearType Rasterizer supposedly uses 32 */ -+ minimum_distance_factor = 64 - gridlines_per_pixel / 3; -+ } -+ -+ else if ( CUR.GS.freeVector.y != 0 && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - - if ( BOUNDS( point, CUR.zp1.n_points ) || -@@ -6237,6 +6658,10 @@ - cvt_dist = 0; - else - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.sph_tweak_flags & SPH_TWEAK_MIRP_CVT_ZERO ) -+ cvt_dist = 0; -+#endif - - /* single width test */ - -@@ -6274,8 +6699,15 @@ - if ( ( org_dist ^ cvt_dist ) < 0 ) - cvt_dist = -cvt_dist; - } -- -- /* control value cutin and round */ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.GS.freeVector.y != 0 && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) -+ { -+ if ( cur_dist < -64 ) cvt_dist -= 16; -+ else if ( cur_dist > 64 && cur_dist < 84) cvt_dist += 32; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ /* control value cut-in and round */ - - if ( ( CUR.opcode & 4 ) != 0 ) - { -@@ -6296,18 +6728,21 @@ - /* `ttinst2.doc', version 1.66, is thus incorrect since */ - /* it implies `>=' instead of `>'. */ - -- if ( FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin ) -+ if ( FT_ABS( cvt_dist - org_dist ) > -+ CUR.GS.control_value_cutin / gridlines_per_pixel ) - cvt_dist = org_dist; - } - - distance = CUR_Func_round( - cvt_dist, -- CUR.tt_metrics.compensations[CUR.opcode & 3] ); -+ CUR.tt_metrics.compensations[CUR.opcode & 3], -+ gridlines_per_pixel ); - } - else - distance = ROUND_None( - cvt_dist, -- CUR.tt_metrics.compensations[CUR.opcode & 3] ); -+ CUR.tt_metrics.compensations[CUR.opcode & 3], -+ gridlines_per_pixel ); - - /* minimum distance test */ - -@@ -6315,18 +6750,63 @@ - { - if ( org_dist >= 0 ) - { -- if ( distance < CUR.GS.minimum_distance ) -- distance = CUR.GS.minimum_distance; -+ if ( distance < FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ) ) -+ distance = FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ); - } - else - { -- if ( distance > -CUR.GS.minimum_distance ) -- distance = -CUR.GS.minimum_distance; -+ if ( distance > -FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ) ) -+ distance = -FT_MulDiv( minimum_distance_factor, -+ CUR.GS.minimum_distance, 64 ); - } - } - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ B1 = CUR.zp1.cur[point].y; -+ -+ /* Round moves if necessary */ -+ if ( CUR.ignore_x_mode && -+ CUR.GS.freeVector.y != 0 && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) -+ distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; -+ -+ if ( CUR.GS.freeVector.y != 0 && -+ ( CUR.opcode & 16 ) == 0 && -+ ( CUR.opcode & 8 ) == 0 && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) -+ distance +=64; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ B2 = CUR.zp1.cur[point].y; -+ -+ /* Reverse move if necessary */ -+ if ( CUR.ignore_x_mode ) -+ { -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && -+ CUR.GS.freeVector.y != 0 && B1 % 64 == 0 && B2 % 64 != 0 ) -+ reverse_move = TRUE; -+ -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && -+ CUR.GS.freeVector.y != 0 && B2 % 64 != 0 && B1 % 64 != 0 ) -+ reverse_move = TRUE; -+ -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES ) && -+ !reverse_move && -+ abs ( B1 - B2 ) >= 64 ) -+ reverse_move = TRUE; -+ } -+ -+ if ( reverse_move ) -+ CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); -+ -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - Fail: - CUR.GS.rp1 = CUR.GS.rp0; - -@@ -6350,8 +6830,14 @@ - FT_F26Dot6 distance; - - FT_UNUSED_ARG; -- -- -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode && CUR.iup_called && -+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) -+ { -+ CUR.error = TT_Err_Invalid_Reference; -+ goto Fail; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { -@@ -6846,6 +7332,15 @@ - contour = 0; - point = 0; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ CUR.iup_called = 1; -+ if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) -+ return; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - do - { - end_point = CUR.pts.contours[contour] - CUR.pts.first_point; -@@ -6915,7 +7410,9 @@ - FT_UShort A; - FT_ULong C; - FT_Long B; -- -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ FT_UShort B1, B2; -+#endif - - #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ -@@ -6988,7 +7485,67 @@ - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /* -+ * Allow delta move if -+ * -+ * - not using ignore_x_mode rendering -+ * - glyph is specifically set to allow it -+ * - glyph is composite and freedom vector is not subpixel vector -+ */ -+ if ( !CUR.ignore_x_mode || -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || -+ ( CUR.is_composite && CUR.GS.freeVector.y != 0 )) -+ CUR_Func_move( &CUR.zp0, A, B ); -+ -+ /* Otherwise apply subpixel hinting and compatibility mode rules */ -+ else if ( CUR.ignore_x_mode ) -+ { -+ if ( CUR.GS.freeVector.y != 0 ) -+ B1 = CUR.zp0.cur[A].y; -+ else -+ B1 = CUR.zp0.cur[A].x; -+ -+ /* Standard Subpixel Hinting: Allow y move */ -+ if ( !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 ) -+ CUR_Func_move( &CUR.zp0, A, B ); -+ -+ /* Compatibility Mode: Allow x or y move if point touched in -+ Y direction */ -+ else if ( CUR.compatibility_mode && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP )) -+ { -+ /* save the y value of the point now; compare after move */ -+ B1 = CUR.zp0.cur[A].y; -+ -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) -+ B = FT_PIX_ROUND( B1 + B ) - B1; -+ -+ /* -+ * Allow delta move if using compatibility_mode, IUP has not -+ * been called, and point is touched on Y. -+ */ -+ if ( !CUR.iup_called && -+ ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) -+ CUR_Func_move( &CUR.zp0, A, B ); -+ } -+ B2 = CUR.zp0.cur[A].y; -+ -+ /* Reverse this move if it results in a disallowed move */ -+ if ( CUR.GS.freeVector.y != 0 && -+ ( ( ( CUR.sph_tweak_flags & -+ SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) && -+ B1 % 64 == 0 && -+ B2 % 64 != 0 ) || -+ ( ( CUR.sph_tweak_flags & -+ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && -+ B1 % 64 != 0 && -+ B2 % 64 != 0 ))) -+ CUR_Func_move( &CUR.zp0, A, -B ); -+ } -+#else - CUR_Func_move( &CUR.zp0, A, B ); -+#endif /* *TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - } - } - else -@@ -7114,26 +7671,116 @@ - Ins_GETINFO( INS_ARG ) - { - FT_Long K; -- -- - K = 0; - -- /* We return MS rasterizer version 1.7 for the font scaler. */ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ /********************************/ -+ /* RASTERIZER VERSION */ -+ /* Selector Bit: 0 */ -+ /* Return Bit(s): 0-7 */ -+ /* */ -+ if ( ( args[0] & 1 ) != 0 && CUR.ignore_x_mode ) -+ { -+ K = CUR.rasterizer_version; -+#ifdef SPH_DEBUG_MORE_VERBOSE -+ printf(" SETTING AS %d\n", CUR.rasterizer_version ); -+#endif -+ } -+ else -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - if ( ( args[0] & 1 ) != 0 ) - K = 35; - -- /* Has the glyph been rotated? */ -+ /********************************/ -+ /* GLYPH ROTATED */ -+ /* Selector Bit: 1 */ -+ /* Return Bit(s): 8 */ -+ /* */ - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) - K |= 0x80; - -- /* Has the glyph been stretched? */ -+ /********************************/ -+ /* GLYPH STRETCHED */ -+ /* Selector Bit: 2 */ -+ /* Return Bit(s): 9 */ -+ /* */ - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) - K |= 1 << 8; - -- /* Are we hinting for grayscale? */ -+ /********************************/ -+ /* HINTING FOR GRAYSCALE */ -+ /* Selector Bit: 5 */ -+ /* Return Bit(s): 12 */ -+ /* */ - if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) - K |= 1 << 12; - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode && CUR.rasterizer_version >= 35 ) -+ { -+ /********************************/ -+ /* HINTING FOR GRAYSCALE */ -+ /* Selector Bit: 5 */ -+ /* Return Bit(s): 12 */ -+ /* */ -+ if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) -+ K |= 1 << 12; -+ -+ /********************************/ -+ /* HINTING FOR SUBPIXEL */ -+ /* Selector Bit: 6 */ -+ /* Return Bit(s): 13 */ -+ /* */ -+ if ( ( args[0] & 64 ) != 0 && -+ CUR.subpixel_hinting && -+ CUR.rasterizer_version >= 37 ) -+ { -+ K |= 1 << 13; -+ -+ /* the stuff below is irrelevant if subpixel_hinting is not set */ -+ -+ /********************************/ -+ /* COMPATIBLE WIDTHS ENABLED */ -+ /* Selector Bit: 7 */ -+ /* Return Bit(s): 14 */ -+ /* */ -+ /* Functionality still needs to be added */ -+ if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) -+ K |= 1 << 14; -+ -+ /********************************/ -+ /* SYMMETRICAL SMOOTHING */ -+ /* Selector Bit: 8 */ -+ /* Return Bit(s): 15 */ -+ /* */ -+ /* Functionality still needs to be added */ -+ if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) -+ K |= 1 << 15; -+ -+ /********************************/ -+ /* HINTING FOR BGR? */ -+ /* Selector Bit: 9 */ -+ /* Return Bit(s): 16 */ -+ /* */ -+ /* Functionality still needs to be added */ -+ if ( ( args[0] & 512 ) != 0 && CUR.bgr ) -+ K |= 1 << 16; -+ -+ if ( CUR.rasterizer_version >= 38 ) -+ { -+ -+ /********************************/ -+ /* SUBPIXEL POSITIONED? */ -+ /* Selector Bit: 10 */ -+ /* Return Bit(s): 17 */ -+ /* */ -+ /* Functionality still needs to be added */ -+ if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) -+ K |= 1 << 17; -+ } -+ } -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - args[0] = K; - } - -@@ -7509,6 +8156,15 @@ - cur = *exc; - #endif - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) -+ { -+ /* ensure some variables are set for this run */ -+ CUR.iup_called = FALSE; -+ CUR.in_delta_function = FALSE; -+ } -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - /* set CVT functions */ - CUR.tt_metrics.ratio = 0; - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) -@@ -7780,7 +8436,13 @@ - break; - - case 0x2B: /* CALL */ -- Ins_CALL( EXEC_ARG_ args ); -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( !CUR.ignore_x_mode || -+ !CUR.iup_called || -+ ( CUR.iup_called && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ Ins_CALL( EXEC_ARG_ args ); - break; - - case 0x2C: /* FDEF */ -@@ -7799,6 +8461,9 @@ - - case 0x30: /* IUP */ - case 0x31: /* IUP */ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( CUR.ignore_x_mode ) CUR.iup_called = TRUE; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - Ins_IUP( EXEC_ARG_ args ); - break; - -@@ -7958,6 +8623,12 @@ - break; - - case 0x5D: /* DELTAP1 */ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ if ( !CUR.ignore_x_mode || -+ !CUR.iup_called || -+ ( CUR.iup_called && -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) ) -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - Ins_DELTAP( EXEC_ARG_ args ); - break; - -diff -Nur freetype-orig/src/truetype/ttinterp.h freetype-subpixel/src/truetype/ttinterp.h ---- freetype-orig/src/truetype/ttinterp.h 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/src/truetype/ttinterp.h 2012-06-16 10:31:58.279833085 -0500 -@@ -68,7 +68,8 @@ - /* Rounding function */ - typedef FT_F26Dot6 - (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, -- FT_F26Dot6 compensation ); -+ FT_F26Dot6 compensation, -+ FT_Int resolution ); - - /* Point displacement along the freedom vector routine */ - typedef void -@@ -107,6 +108,44 @@ - } TT_CallRec, *TT_CallStack; - - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+ /*************************************************************************/ -+ /* */ -+ /* This structure defines a rule used to tweak subpixel hinting for */ -+ /* various fonts. "", 0, "", NULL value indicates to match any value. */ -+ /* */ -+ -+ typedef struct SPH_TweakRule_ -+ { -+ const char family[32]; -+ const int ppem; -+ const char style[32]; -+ const FT_ULong glyph; -+ -+ } SPH_TweakRule; -+ -+ -+ typedef struct SPH_ScaleRule_ -+ { -+ const char family[32]; -+ const int ppem; -+ const char style[32]; -+ const FT_ULong glyph; -+ const float scale; -+ } SPH_ScaleRule; -+ -+#define MAX_CLASS_MEMBERS 100 -+ -+ typedef struct Font_Class_ -+ { -+ const char name[32]; -+ const char member[MAX_CLASS_MEMBERS][32]; -+ } Font_Class; -+ -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ -+ - /*************************************************************************/ - /* */ - /* The main structure for the interpreter which collects all necessary */ -@@ -218,6 +257,37 @@ - - FT_Bool grayscale; /* are we hinting for grayscale? */ - -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ TT_Round_Func func_round_sphn; /* subpixel rounding function */ -+ -+ FT_Bool grayscale_hinting; /* Using grayscale hinting? */ -+ FT_Bool subpixel_hinting; /* Using subpixel hinting? */ -+ FT_Bool native_hinting; /* Using native hinting? */ -+ FT_Bool ignore_x_mode; /* Standard rendering mode for */ -+ /* subpixel hinting. On if gray */ -+ /* or subpixel hinting is on ) */ -+ FT_Bool compatibility_mode;/* Additional exceptions to */ -+ /* native TT rules for legacy */ -+ /* fonts. Implies ignore_x_mode. */ -+ -+ /* The following 3 aren't fully implemented but here for MS rasterizer */ -+ /* compatibility. */ -+ FT_Bool compatible_widths; /* compatible widths? */ -+ FT_Bool symmetrical_smoothing;/* symmetrical_smoothing? */ -+ FT_Bool bgr; /* bgr instead of rgb? */ -+ FT_Bool subpixel_positioned; /* MS DW subpixel positioned */ -+ -+ FT_Int rasterizer_version; /* MS rasterizer version */ -+ -+ FT_Bool iup_called; /* IUP called for glyph? */ -+ FT_Bool in_delta_function; /* inside an inline delta func? */ -+ -+ FT_ULong sph_tweak_flags; /* flags to control hint tweaks */ -+ -+ FT_Int num_delta_funcs; -+ FT_ULong inline_delta_funcs[5]; -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ - } TT_ExecContextRec; - - -diff -Nur freetype-orig/src/truetype/ttobjs.h freetype-subpixel/src/truetype/ttobjs.h ---- freetype-orig/src/truetype/ttobjs.h 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-subpixel/src/truetype/ttobjs.h 2012-06-15 07:31:12.163985155 -0500 -@@ -178,6 +178,7 @@ - FT_Long end; /* where does it end? */ - FT_UInt opc; /* function #, or instruction code */ - FT_Bool active; /* is it active? */ -+ FT_Bool inline_delta; /* is function that defines inline delta? */ - - } TT_DefRecord, *TT_DefArray; - -@@ -190,7 +191,7 @@ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; -- FT_F26Dot6 ox, oy; /* offsets */ -+ FT_F26Dot6 ox, oy; /* offsets */ - - } TT_Transform; - -diff -Nur freetype-orig/src/truetype/ttsubpix.c freetype-subpixel/src/truetype/ttsubpix.c ---- freetype-orig/src/truetype/ttsubpix.c 1969-12-31 18:00:00.000000000 -0600 -+++ freetype-subpixel/src/truetype/ttsubpix.c 2012-06-16 10:32:09.670447034 -0500 -@@ -0,0 +1,261 @@ -+/***************************************************************************/ -+/* */ -+/* ttsubpix.c */ -+/* */ -+/* TrueType Subpixel Hinting. */ -+/* */ -+/* Copyright 2010-2011 by */ -+/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -+/* */ -+/* This file is part of the FreeType project, and may only be used, */ -+/* modified, and distributed under the terms of the FreeType project */ -+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -+/* this file you indicate that you have read the license and */ -+/* understand and accept it fully. */ -+/* */ -+/***************************************************************************/ -+ -+#include <ft2build.h> -+#include FT_INTERNAL_DEBUG_H -+#include FT_INTERNAL_CALC_H -+#include FT_INTERNAL_STREAM_H -+#include FT_INTERNAL_SFNT_H -+#include FT_TRUETYPE_TAGS_H -+#include FT_OUTLINE_H -+ -+#include "ttsubpix.h" -+ -+ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+ FT_LOCAL_DEF( FT_Bool ) -+ is_member_of_family_class( const FT_String* detected_font_name, -+ const FT_String* rule_font_name ) -+ { -+ FT_UInt i, j; -+ -+ /* If font name matches rule family */ -+ if ( strcmp( detected_font_name, rule_font_name ) == 0 ) return TRUE; -+ -+ /* If font name is a wildcard "" */ -+ if ( strcmp( rule_font_name, "" ) == 0 ) return TRUE; -+ -+ /* If font name is contained in a class list */ -+ for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) -+ { -+ if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) -+ { -+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ ) -+ { -+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) -+ continue; -+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j], detected_font_name ) == 0 ) -+ return TRUE; -+ } -+ } -+ } -+ return FALSE; -+ } -+ -+ -+ FT_LOCAL_DEF( FT_Bool ) -+ is_member_of_style_class( const FT_String* detected_font_style, -+ const FT_String* rule_font_style ) -+ { -+ FT_UInt i, j; -+ -+ /* If font style matches rule style */ -+ if ( strcmp( detected_font_style, rule_font_style ) == 0 ) return TRUE; -+ -+ /* If font style is a wildcard "" */ -+ if ( strcmp( rule_font_style, "" ) == 0 ) return TRUE; -+ -+ /* If font style is contained in a class list */ -+ for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) -+ { -+ if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) -+ { -+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ ) -+ { -+ if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) -+ continue; -+ if ( strcmp( STYLE_CLASS_Rules[i].member[j], detected_font_style ) == 0 ) -+ return TRUE; -+ } -+ } -+ } -+ return FALSE; -+ } -+ -+ -+ FT_LOCAL_DEF( FT_Bool ) -+ sph_test_tweak( TT_Face face, -+ FT_String* family, -+ int ppem, -+ FT_String* style, -+ FT_UInt glyph_index, -+ SPH_TweakRule* rule, -+ FT_UInt num_rules ) -+ { -+ FT_UInt i; -+ -+ -+ /* rule checks may be able to be optimized further */ -+ for ( i = 0; i < num_rules; i++ ) -+ { -+ if ( family && -+ ( is_member_of_family_class ( family, rule[i].family ) ) ) -+ if ( rule[i].ppem == 0 || -+ rule[i].ppem == ppem ) -+ if ( style && -+ is_member_of_style_class ( style, rule[i].style ) ) -+ if ( rule[i].glyph == 0 || -+ FT_Get_Char_Index( (FT_Face)face, -+ rule[i].glyph ) == glyph_index ) -+ return TRUE; -+ } -+ return FALSE; -+ } -+ -+ -+ FT_LOCAL_DEF( float ) -+ scale_test_tweak( TT_Face face, -+ FT_String* family, -+ int ppem, -+ FT_String* style, -+ FT_UInt glyph_index, -+ SPH_ScaleRule* rule, -+ FT_UInt num_rules ) -+ { -+ FT_UInt i; -+ -+ -+ /* rule checks may be able to be optimized further */ -+ for ( i = 0; i < num_rules; i++ ) -+ { -+ if ( family && -+ ( is_member_of_family_class ( family, rule[i].family ) ) ) -+ if ( rule[i].ppem == 0 || -+ rule[i].ppem == ppem ) -+ if ( style && -+ is_member_of_style_class( style, rule[i].style ) ) -+ if ( rule[i].glyph == 0 || -+ FT_Get_Char_Index( (FT_Face)face, -+ rule[i].glyph ) == glyph_index ) -+ return rule[i].scale; -+ } -+ return 1.0; -+ } -+ -+#define TWEAK_RULES( x ) \ -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ -+ x##_Rules, x##_RULES_SIZE ) ) \ -+ loader->exec->sph_tweak_flags |= SPH_TWEAK_##x; -+ -+#define TWEAK_RULES_EXCEPTIONS( x ) \ -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \ -+ x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \ -+ loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x; -+ -+ FT_LOCAL_DEF( void ) -+ sph_set_tweaks( TT_Loader loader, -+ FT_UInt glyph_index ) -+ { -+ TT_Face face = (TT_Face)loader->face; -+ FT_String* family = face->root.family_name; -+ int ppem = loader->size->metrics.x_ppem; -+ FT_String* style = face->root.style_name; -+ -+ /* Don't apply rules if style isn't set */ -+ if ( !face->root.style_name ) return; -+ -+#ifdef SPH_DEBUG_MORE_VERBOSE -+ printf( "%s,%d,%s,%c=%d ", family, ppem, style, glyph_index, glyph_index ); -+#endif -+ -+ TWEAK_RULES( PIXEL_HINTING ); -+ -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING ) -+ { -+ loader->exec->ignore_x_mode = FALSE; -+ return; -+ } -+ -+ TWEAK_RULES( ALLOW_X_DMOVE ); -+ TWEAK_RULES( ALLOW_X_DMOVEX ); -+ TWEAK_RULES( ALLOW_X_MOVE_ZP2 ); -+ TWEAK_RULES( ALWAYS_DO_DELTAP ); -+ TWEAK_RULES( ALWAYS_SKIP_DELTAP ); -+ TWEAK_RULES( DEEMBOLDEN ); -+ TWEAK_RULES( DELTAP_SKIP_EXAGGERATED_VALUES ); -+ TWEAK_RULES( DO_SHPIX ); -+ TWEAK_RULES( EMBOLDEN ); -+ TWEAK_RULES( MIAP_HACK ); -+ TWEAK_RULES( NORMAL_ROUND ); -+ TWEAK_RULES( NO_ALIGNRP_AFTER_IUP ); -+ TWEAK_RULES( NO_CALL_AFTER_IUP ); -+ TWEAK_RULES( NO_DELTAP_AFTER_IUP ); -+ TWEAK_RULES( RASTERIZER_35 ); -+ TWEAK_RULES( SKIP_INLINE_DELTAS ); -+ TWEAK_RULES( SKIP_IUP ); -+ TWEAK_RULES( MIRP_CVT_ZERO ); -+ -+ TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES ); -+ TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES ); -+ -+ TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES ); -+ TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES ); -+ -+ TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES ); -+ TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES ); -+ -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) -+ { -+ if ( loader->exec->rasterizer_version != 35 ) -+ { -+ loader->exec->rasterizer_version = 35; -+ /* must re-execute fpgm */ -+ loader->exec->size->cvt_ready = FALSE; -+ tt_size_ready_bytecode( loader->exec->size, -+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); -+ } -+ } -+ else -+ { -+ if ( loader->exec->rasterizer_version == 35 ) -+ { -+ loader->exec->rasterizer_version = 37; -+ /* must re-execute fpgm */ -+ loader->exec->size->cvt_ready = FALSE; -+ tt_size_ready_bytecode( loader->exec->size, -+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) ); -+ } -+ } -+ -+ if ( IS_HINTED( loader->load_flags ) ) -+ { -+ TWEAK_RULES( TIMES_NEW_ROMAN_HACK ); -+ TWEAK_RULES( COURIER_NEW_2_HACK ); -+ } -+ -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, -+ COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) ) -+ { -+ loader->exec->compatibility_mode |= TRUE; -+ loader->exec->ignore_x_mode |= TRUE; -+ } -+ else -+ loader->exec->compatibility_mode &= FALSE; -+ -+ if ( IS_HINTED( loader->load_flags ) ) -+ { -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, -+ COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) ) -+ loader->exec->compatible_widths |= TRUE; -+ } -+ } -+ -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ -+ -+/* END */ -diff -Nur freetype-orig/src/truetype/ttsubpix.h freetype-subpixel/src/truetype/ttsubpix.h ---- freetype-orig/src/truetype/ttsubpix.h 1969-12-31 18:00:00.000000000 -0600 -+++ freetype-subpixel/src/truetype/ttsubpix.h 2012-06-16 10:30:26.121956142 -0500 -@@ -0,0 +1,778 @@ -+/***************************************************************************/ -+/* */ -+/* ttsubpix.h */ -+/* */ -+/* TrueType Subpixel Hinting. */ -+/* */ -+/* Copyright 2010-2011 by */ -+/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -+/* */ -+/* This file is part of the FreeType project, and may only be used, */ -+/* modified, and distributed under the terms of the FreeType project */ -+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -+/* this file you indicate that you have read the license and */ -+/* understand and accept it fully. */ -+/* */ -+/***************************************************************************/ -+ -+#ifndef __TTSUBPIX_H__ -+#define __TTSUBPIX_H__ -+ -+#include <ft2build.h> -+#include "ttobjs.h" -+#include "ttinterp.h" -+ -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING -+ -+ /*************************************************************************/ -+ /* */ -+ /* Tweak flags that are set for each glyph by the below rules */ -+ /* */ -+ /* */ -+#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001 -+#define SPH_TWEAK_ALLOW_X_DMOVEX 0x0000002 -+#define SPH_TWEAK_ALLOW_X_MOVE_ZP2 0x0000004 -+#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000008 -+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000010 -+#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000020 -+#define SPH_TWEAK_DEEMBOLDEN 0x0000040 -+#define SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES 0x0000080 -+#define SPH_TWEAK_DO_SHPIX 0x0000100 -+#define SPH_TWEAK_EMBOLDEN 0x0000200 -+#define SPH_TWEAK_MIAP_HACK 0x0000400 -+#define SPH_TWEAK_NORMAL_ROUND 0x0000800 -+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0001000 -+#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0002000 -+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0004000 -+#define SPH_TWEAK_PIXEL_HINTING 0x0008000 -+#define SPH_TWEAK_RASTERIZER_35 0x0010000 -+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0020000 -+#define SPH_TWEAK_SKIP_INLINE_DELTAS 0x0040000 -+#define SPH_TWEAK_SKIP_IUP 0x0080000 -+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0100000 -+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0200000 -+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0400000 -+#define SPH_TWEAK_MIRP_CVT_ZERO 0x0800000 -+ -+ -+ FT_LOCAL( FT_Bool ) -+ sph_test_tweak( TT_Face face, -+ FT_String* family, -+ int ppem, -+ FT_String* style, -+ FT_UInt glyph_index, -+ SPH_TweakRule* rule, -+ FT_UInt num_rules ); -+ -+ FT_LOCAL_DEF( float ) -+ scale_test_tweak( TT_Face face, -+ FT_String* family, -+ int ppem, -+ FT_String* style, -+ FT_UInt glyph_index, -+ SPH_ScaleRule* rule, -+ FT_UInt num_rules ); -+ -+ FT_LOCAL( void ) -+ sph_set_tweaks( TT_Loader loader, -+ FT_UInt glyph_index ); -+ -+ -+ /*************************************************************************/ -+ /* */ -+ /* These rules affect how the TT Interpreter does hinting, with the */ -+ /* goal of doing subpixel hinting by (in general) ignoring x moves. */ -+ /* Some of these rules are fixes that go above and beyond the */ -+ /* stated techniques in the MS whitepaper on Cleartype, due to */ -+ /* artifacts in many glyphs. So, these rules make some glyphs render */ -+ /* better than they do in the MS rasterizer. */ -+ /* */ -+ /* "" string or 0 int/char indicates to apply to all glyphs. */ -+ /* "-" used as dummy placeholders, but any non-matching string works. */ -+ /* */ -+ /* Some of this could arguably be implemented in fontconfig, however: */ -+ /* */ -+ /* - Fontconfig can't set things on a glyph-by-glyph basis. */ -+ /* - The tweaks that happen here are very low-level, from an average */ -+ /* user's point of view and are best implemented in the hinter */ -+ /* */ -+ /* The goal is to make the subpixel hinting techniques as generalized */ -+ /* as possible across all fonts to prevent the need for extra rules such */ -+ /* as these. */ -+ /* */ -+ /* The rule structure is designed so that entirely new rules can easily */ -+ /* be added when a new compatibility feature is discovered. */ -+ /* */ -+ /* The rule structures could also use some enhancement to handle ranges. */ -+ /* */ -+ /* ****************** WORK IN PROGRESS ******************* */ -+ /* */ -+ -+#define SPH_OPTION_BITMAP_WIDTHS FALSE -+#define SPH_OPTION_SET_SUBPIXEL TRUE -+#define SPH_OPTION_SET_GRAYSCALE FALSE -+#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE -+#define SPH_OPTION_SET_RASTERIZER_VERSION 37 -+#define SPH_OPTION_GRIDLINES_PER_PIXEL_X 64 -+#define SPH_OPTION_GRIDLINES_PER_PIXEL_Y 1 -+ -+#define MAX_CLASS_MEMBERS 100 -+ -+/* Define this to force natural (i.e. not bitmap-compatible) widths. */ -+/* The default leans strongly towards natural widths except for a few */ -+/* legacy fonts where a selective combination produces nicer results. */ -+/* #define FORCE_NATURAL_WIDTHS */ -+ -+ -+ /* These are "classes" of fonts that can be grouped together and used in */ -+ /* rules below. A blank entry "" is required at the end of these! */ -+#define FAMILY_CLASS_RULES_SIZE 7 -+ Font_Class FAMILY_CLASS_Rules -+ [FAMILY_CLASS_RULES_SIZE] = -+ { -+ { "MS Legacy Fonts", { "Aharoni", -+ "Andale Mono", -+ "Andalus", -+ "Angsana New", -+ "AngsanaUPC", -+ "Arabic Transparent", -+ "Arial Black", -+ "Arial Narrow", -+ "Arial Unicode MS", -+ "Arial", -+ "Batang", -+ "Browallia New", -+ "BrowalliaUPC", -+ "Comic Sans MS", -+ "Cordia New", -+ "CordiaUPC", -+ "Courier New", -+ "DFKai-SB", -+ "David Transparent", -+ "David", -+ "DilleniaUPC", -+ "Estrangelo Edessa", -+ "EucrosiaUPC", -+ "FangSong_GB2312", -+ "Fixed Miriam Transparent", -+ "FrankRuehl", -+ "Franklin Gothic Medium", -+ "FreesiaUPC", -+ "Garamond", -+ "Gautami", -+ "Georgia", -+ "Gulim", -+ "Impact", -+ "IrisUPC", -+ "JasmineUPC", -+ "KaiTi_GB2312", -+ "KodchiangUPC", -+ "Latha", -+ "Levenim MT", -+ "LilyUPC", -+ "Lucida Console", -+ "Lucida Sans Unicode", -+ "MS Gothic", -+ "MS Mincho", -+ "MV Boli", -+ "Mangal", -+ "Marlett", -+ "Microsoft Sans Serif", -+ "Mingliu", -+ "Miriam Fixed", -+ "Miriam Transparent", -+ "Miriam", -+ "Narkisim", -+ "Palatino Linotype", -+ "Raavi", -+ "Rod Transparent", -+ "Rod", -+ "Shruti", -+ "SimHei", -+ "Simplified Arabic Fixed", -+ "Simplified Arabic", -+ "Simsun", -+ "Sylfaen", -+ "Symbol", -+ "Tahoma", -+ "Times New Roman", -+ "Traditional Arabic", -+ "Trebuchet MS", -+ "Tunga", -+ "Verdana", -+ "Webdings", -+ "Wingdings", "", }, }, -+ { "Core MS Legacy Fonts", { "Arial Black", -+ "Arial Narrow", -+ "Arial Unicode MS", -+ "Arial", -+ "Comic Sans MS", -+ "Courier New", -+ "Garamond", -+ "Georgia", -+ "Impact", -+ "Lucida Console", -+ "Lucida Sans Unicode", -+ "Microsoft Sans Serif", -+ "Palatino Linotype", -+ "Tahoma", -+ "Times New Roman", -+ "Trebuchet MS", -+ "Verdana", "", }, }, -+ { "Apple Legacy Fonts", { "Geneva", -+ "Times", -+ "Monaco", -+ "Century", -+ "Chalkboard", -+ "Lobster", -+ "Century Gothic", -+ "Optima", -+ "Lucida Grande", -+ "Gill Sans", -+ "Baskerville", -+ "Helvetica", -+ "Helvetica Neue", "", }, }, -+ { "Legacy Sans Fonts", { "Andale Mono", -+ "Arial Unicode MS", -+ "Arial", -+ "Century Gothic", -+ "Comic Sans MS", -+ "Franklin Gothic Medium", -+ "Geneva", -+ "Lucida Console", -+ "Lucida Grande", -+ "Lucida Sans Unicode", -+ "Microsoft Sans Serif", -+ "Monaco", -+ "Tahoma", -+ "Trebuchet MS", -+ "Verdana", "", }, }, -+ { "Misc Legacy Fonts", { "Dark Courier", "", }, }, -+ { "Verdana Clones", { "DejaVu Sans", -+ "Bitstream Vera Sans", "", }, }, -+ { "Verdana and Clones", { "DejaVu Sans", -+ "Bitstream Vera Sans", -+ "Verdana", "", }, }, -+}; -+ -+ -+ /* Define "classes" of styles that can be grouped together and used in */ -+ /* rules below. A blank entry "" is required at the end of these! */ -+#define STYLE_CLASS_RULES_SIZE 5 -+ Font_Class STYLE_CLASS_Rules -+ [STYLE_CLASS_RULES_SIZE] = -+ { -+ { "Regular Class", { "Regular", -+ "Book", -+ "Medium", -+ "Roman", -+ "Normal", "", }, }, -+ { "Regular/Italic Class", { "Regular", -+ "Book", -+ "Medium", -+ "Italic", -+ "Oblique", -+ "Roman", -+ "Normal", "", }, }, -+ { "Bold/BoldItalic Class", { "Bold", -+ "Bold Italic", -+ "Black", "", }, }, -+ { "Bold/Italic/BoldItalic Class", { "Bold", -+ "Bold Italic", -+ "Black", -+ "Italic", -+ "Oblique", "", }, }, -+ { "Regular/Bold Class", { "Regular", -+ "Book", -+ "Medium", -+ "Normal", -+ "Roman", -+ "Bold", -+ "Black", "", }, }, -+ }; -+ -+ -+ -+ /* Special fixes for known legacy fonts */ -+ /* This is the primary workhorse rule for legacy fonts */ -+#define COMPATIBILITY_MODE_RULES_SIZE 4 -+ SPH_TweakRule COMPATIBILITY_MODE_Rules -+ [COMPATIBILITY_MODE_RULES_SIZE] = -+ { -+ { "MS Legacy Fonts", 0, "", 0 }, -+ { "Apple Legacy Fonts", 0, "", 0 }, -+ { "Misc Legacy Fonts", 0, "", 0 }, -+ { "Verdana Clones", 0, "", 0 }, -+ }; -+ -+ -+ /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting */ -+#define PIXEL_HINTING_RULES_SIZE 4 -+ SPH_TweakRule PIXEL_HINTING_Rules -+ [PIXEL_HINTING_RULES_SIZE] = -+ { -+ /* These characters are almost always safe */ -+ { "", 0, "", '<' }, -+ { "", 0, "", '>' }, -+ /* Fixes the vanishing stem */ -+ { "Times New Roman", 0, "Bold", 'A' }, -+ { "Times New Roman", 0, "Bold", 'V' }, -+ }; -+ -+ -+ /* According to Greg Hitchcock and the MS whitepaper, this should work */ -+ /* on all legacy MS fonts, but creates artifacts with some. Only using */ -+ /* where absolutely necessary. */ -+#define SKIP_INLINE_DELTAS_RULES_SIZE 1 -+ SPH_TweakRule SKIP_INLINE_DELTAS_Rules -+ [SKIP_INLINE_DELTAS_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ -+ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */ -+#define DO_SHPIX_RULES_SIZE 1 -+ SPH_TweakRule DO_SHPIX_Rules -+ [DO_SHPIX_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ -+ /* Skip Y moves that start with a point that is not on a Y pixel */ -+ /* boundary and don't move that point to a Y pixel boundary. */ -+#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 8 -+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules -+ [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] = -+ { -+ /* fix vwxyz thinness*/ -+ { "Consolas", 0, "Regular", 0 }, -+ /* fix tiny gap at top of m */ -+ { "Arial", 0, "Regular", 'm' }, -+ /* Fix thin middle stems */ -+ { "Core MS Legacy Fonts", 0, "Regular/Bold Class", 'N' }, -+ { "Lucida Grande", 0, "", 'N' }, -+ { "Legacy Sans Fonts", 0, "", L'и' }, -+ { "Verdana Clones", 0, "",'N' }, -+ { "Ubuntu", 0, "Regular Class", 'N' }, -+ /* Fix misshapen x */ -+ { "Verdana", 0, "Bold", 'x' }, -+ }; -+ -+#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 4 -+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions -+ [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = -+ { -+ { "Tahoma", 0, "", 'N' }, -+ { "Comic Sans MS", 0, "", 'N' }, -+ { "Verdana", 0, "Regular/Bold Class", 'N' }, -+ { "Verdana", 11, "Bold", 'x' }, -+ }; -+ -+ -+ -+ /* Skip Y moves that move a point off a Y pixel boundary */ -+ /* This fixes Tahoma, Trebuchet oddities and some issues with `$' */ -+#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 5 -+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules -+ [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] = -+ { -+ { "MS Legacy Fonts", 0, "", 0 }, -+ { "Apple Legacy Fonts", 0, "", 0 }, -+ { "Misc Legacy Fonts", 0, "", 0 }, -+ { "Ubuntu", 0, "Regular Class", 0 }, -+ { "Verdana Clones", 0, "", 0 }, -+ }; -+ -+ -+#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1 -+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions -+ [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ -+ /* Round moves that don't move a point to a Y pixel boundary */ -+#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 3 -+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules -+ [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] = -+ { -+ /* Droid font instructions don't snap Y to pixels */ -+ { "Droid Sans", 0, "Regular/Italic Class", 0 }, -+ { "Droid Sans Mono", 0, "", 0 }, -+ { "Ubuntu", 0, "", 0 }, -+ }; -+ -+#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 3 -+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions -+ [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] = -+ { -+ { "Droid Sans", 12, "Bold", 0 }, -+ { "Droid Sans", 13, "Bold", 0 }, -+ { "Droid Sans", 16, "Bold", 0 }, -+ }; -+ -+ /* Allow a Direct_Move_X along X freedom vector if matched */ -+#define ALLOW_X_DMOVEX_RULES_SIZE 2 -+ SPH_TweakRule ALLOW_X_DMOVEX_Rules -+ [ALLOW_X_DMOVEX_RULES_SIZE] = -+ { -+ /* Creates a more consistent appearance for these */ -+ { "Arial", 13, "Regular", 'e' }, -+ { "Arial", 13, "Regular", 'o' }, -+ }; -+ -+ /* Allow a Direct_Move along X freedom vector if matched */ -+#define ALLOW_X_DMOVE_RULES_SIZE 3 -+ SPH_TweakRule ALLOW_X_DMOVE_Rules -+ [ALLOW_X_DMOVE_RULES_SIZE] = -+ { -+ /* Creates a more consistent appearance for these */ -+ { "Arial", 13, "Regular", 'e' }, -+ { "Arial", 13, "Regular", 'o' }, -+ /* Fixes vanishing diagonal in 4 */ -+ { "Verdana", 0, "Regular", '4' }, -+ }; -+ -+ /* Allow a ZP2 move along freedom vector if matched; */ -+ /* This is called from SHP, SHPIX, SHC, SHZ */ -+#define ALLOW_X_MOVE_ZP2_RULES_SIZE 1 -+ SPH_TweakRule ALLOW_X_MOVE_ZP2_Rules -+ [ALLOW_X_MOVE_ZP2_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ /* Return MS rasterizer version 35 if matched */ -+#define RASTERIZER_35_RULES_SIZE 8 -+ SPH_TweakRule RASTERIZER_35_Rules -+ [RASTERIZER_35_RULES_SIZE] = -+ { -+ /* This seems to be the only way to make these look good */ -+ { "Times New Roman", 0, "Regular", 'i' }, -+ { "Times New Roman", 0, "Regular", 'j' }, -+ { "Times New Roman", 0, "Regular", 'm' }, -+ { "Times New Roman", 0, "Regular", 'r' }, -+ { "Times New Roman", 0, "Regular", 'a' }, -+ { "Times New Roman", 0, "Regular", 'n' }, -+ { "Times New Roman", 0, "Regular", 'p' }, -+ { "Times", 0, "", 0 }, -+ }; -+ -+ /* Don't round to the subpixel grid. Round to pixel grid. */ -+#define NORMAL_ROUND_RULES_SIZE 2 -+ SPH_TweakRule NORMAL_ROUND_Rules -+ [NORMAL_ROUND_RULES_SIZE] = -+ { -+ /* Fix point "explosions" */ -+ { "Courier New", 0, "", 0 }, -+ { "Verdana", 10, "Regular", '4' }, -+ }; -+ -+ /* Skip IUP instructions if matched */ -+#define SKIP_IUP_RULES_SIZE 1 -+ SPH_TweakRule SKIP_IUP_Rules -+ [SKIP_IUP_RULES_SIZE] = -+ { -+ { "Arial", 13, "Regular", 'a' }, -+ }; -+ -+ /* Skip MIAP Twilight hack if matched */ -+#define MIAP_HACK_RULES_SIZE 1 -+ SPH_TweakRule MIAP_HACK_Rules -+ [MIAP_HACK_RULES_SIZE] = -+ { -+ { "Geneva", 12, "", 0 }, -+ }; -+ -+ /* Skip DELTAP instructions if matched */ -+#define ALWAYS_SKIP_DELTAP_RULES_SIZE 13 -+ SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules -+ [ALWAYS_SKIP_DELTAP_RULES_SIZE] = -+ { -+ { "Georgia", 0, "Regular", 'k' }, -+ /* fixes problems with W M w */ -+ { "Trebuchet MS", 0, "Italic", 0 }, -+ { "Trebuchet MS", 14, "Regular", 'e' }, -+ { "Arial", 11, "Regular", 's' }, -+ { "Verdana", 10, "Regular", 0 }, -+ { "Verdana", 9, "Regular", 0 }, -+ { "Legacy Sans Fonts", 0, "", L'й' }, -+ { "Arial", 10, "Regular", '6' }, -+ { "Arial", 0, "Bold/BoldItalic Class", 'a' }, -+ /* Make horizontal stems consistent with the rest */ -+ { "Arial", 24, "Bold", 's' }, -+ { "Arial", 25, "Bold", 's' }, -+ { "Arial", 24, "Bold", 'a' }, -+ { "Arial", 25, "Bold", 'a' }, -+ }; -+ -+ /* Always do DELTAP instructions if matched */ -+#define ALWAYS_DO_DELTAP_RULES_SIZE 2 -+ SPH_TweakRule ALWAYS_DO_DELTAP_Rules -+ [ALWAYS_DO_DELTAP_RULES_SIZE] = -+ { -+ { "Verdana Clones", 17, "Regular Class", 'K' }, -+ { "Verdana Clones", 17, "Regular Class", 'k' }, -+ }; -+ -+ /* Do an extra RTG instruction in DELTAP if matched */ -+#define DELTAP_RTG_RULES_SIZE 1 -+ SPH_TweakRule DELTAP_RTG_Rules -+ [DELTAP_RTG_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ /* Force CVT distance to zero in MIRP */ -+#define MIRP_CVT_ZERO_RULES_SIZE 1 -+ SPH_TweakRule MIRP_CVT_ZERO_Rules -+ [MIRP_CVT_ZERO_RULES_SIZE] = -+ { -+ { "Verdana", 0, "Regular", 0 }, -+ }; -+ -+ /* Skip moves that meet or exceed 1 pixel */ -+#define DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE 2 -+ SPH_TweakRule DELTAP_SKIP_EXAGGERATED_VALUES_Rules -+ [DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE] = -+ { -+ /* Fix vanishing stems */ -+ { "Ubuntu", 0, "Regular", 'M' }, -+ /* Fix X at larger ppems */ -+ { "Segoe UI", 0, "Light", 0 }, -+ }; -+ -+ /* Don't allow ALIGNRP after IUP */ -+#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 4 -+ SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules -+ [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] = -+ { -+ /* Prevent creation of dents in outline */ -+ { "Courier New", 0, "Bold", 'C' }, -+ { "Courier New", 0, "Bold", 'D' }, -+ { "Courier New", 0, "Bold", 'Q' }, -+ { "Courier New", 0, "Bold", '0' }, -+ }; -+ -+ /* Don't allow DELTAP after IUP */ -+#define NO_DELTAP_AFTER_IUP_RULES_SIZE 2 -+ SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules -+ [NO_DELTAP_AFTER_IUP_RULES_SIZE] = -+ { -+ { "Arial", 0, "Bold", 'N' }, -+ { "Verdana", 0, "Regular", '4' }, -+ }; -+ -+ /* Don't allow CALL after IUP */ -+#define NO_CALL_AFTER_IUP_RULES_SIZE 4 -+ SPH_TweakRule NO_CALL_AFTER_IUP_Rules -+ [NO_CALL_AFTER_IUP_RULES_SIZE] = -+ { -+ /* Prevent creation of dents in outline */ -+ { "Courier New", 0, "Bold", 'O' }, -+ { "Courier New", 0, "Bold", 'Q' }, -+ { "Courier New", 0, "Bold", 'k' }, -+ { "Courier New", 0, "Bold Italic", 'M' }, -+ }; -+ -+ /* De-embolden these glyphs slightly */ -+#define DEEMBOLDEN_RULES_SIZE 9 -+ SPH_TweakRule DEEMBOLDEN_Rules -+ [DEEMBOLDEN_RULES_SIZE] = -+ { -+ { "Courier New", 0, "Bold", 'A' }, -+ { "Courier New", 0, "Bold", 'W' }, -+ { "Courier New", 0, "Bold", 'w' }, -+ { "Courier New", 0, "Bold", 'M' }, -+ { "Courier New", 0, "Bold", 'X' }, -+ { "Courier New", 0, "Bold", 'K' }, -+ { "Courier New", 0, "Bold", 'x' }, -+ { "Courier New", 0, "Bold", 'z' }, -+ { "Courier New", 0, "Bold", 'v' }, -+ }; -+ -+ /* Embolden these glyphs slightly */ -+#define EMBOLDEN_RULES_SIZE 5 -+ SPH_TweakRule EMBOLDEN_Rules -+ [EMBOLDEN_RULES_SIZE] = -+ { -+ { "Courier New", 12, "Italic", 'z' }, -+ { "Courier New", 11, "Italic", 'z' }, -+ { "Courier New", 10, "Italic", 'z' }, -+ { "Courier New", 0, "Regular", 0 }, -+ { "Courier New", 0, "Italic", 0 }, -+ }; -+ -+ /* Do an extra RDTG instruction in DELTAP if matched */ -+#define DELTAP_RDTG_RULES_SIZE 1 -+ SPH_TweakRule DELTAP_RDTG_Rules -+ [DELTAP_RDTG_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+ /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */ -+ /* similar to Windows XP. */ -+#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12 -+ SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules -+ [TIMES_NEW_ROMAN_HACK_RULES_SIZE] = -+ { -+ { "Times New Roman", 16, "Italic", '2' }, -+ { "Times New Roman", 16, "Italic", '5' }, -+ { "Times New Roman", 16, "Italic", '7' }, -+ { "Times New Roman", 16, "Regular", '2' }, -+ { "Times New Roman", 16, "Regular", '5' }, -+ { "Times New Roman", 16, "Regular", '7' }, -+ { "Times New Roman", 17, "Italic", '2' }, -+ { "Times New Roman", 17, "Italic", '5' }, -+ { "Times New Roman", 17, "Italic", '7' }, -+ { "Times New Roman", 17, "Regular", '2' }, -+ { "Times New Roman", 17, "Regular", '5' }, -+ { "Times New Roman", 17, "Regular", '7' }, -+ }; -+ -+ -+ /* This fudges distance on 2 to get rid of the vanishing stem issue. */ -+ /* A real solution to this is certainly welcome. */ -+#define COURIER_NEW_2_HACK_RULES_SIZE 15 -+ SPH_TweakRule COURIER_NEW_2_HACK_Rules -+ [COURIER_NEW_2_HACK_RULES_SIZE] = -+ { -+ { "Courier New", 10, "Regular", '2' }, -+ { "Courier New", 11, "Regular", '2' }, -+ { "Courier New", 12, "Regular", '2' }, -+ { "Courier New", 13, "Regular", '2' }, -+ { "Courier New", 14, "Regular", '2' }, -+ { "Courier New", 15, "Regular", '2' }, -+ { "Courier New", 16, "Regular", '2' }, -+ { "Courier New", 17, "Regular", '2' }, -+ { "Courier New", 18, "Regular", '2' }, -+ { "Courier New", 19, "Regular", '2' }, -+ { "Courier New", 20, "Regular", '2' }, -+ { "Courier New", 21, "Regular", '2' }, -+ { "Courier New", 22, "Regular", '2' }, -+ { "Courier New", 23, "Regular", '2' }, -+ { "Courier New", 24, "Regular", '2' }, -+ }; -+ -+ -+#ifndef FORCE_NATURAL_WIDTHS -+ -+ /* Use compatible widths with these glyphs. Compatible widths is always */ -+ /* on when doing B/W TrueType instructing, but is used selectively here, */ -+ /* typically on glyphs with 3 or more vertical stems. */ -+#define COMPATIBLE_WIDTHS_RULES_SIZE 36 -+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules -+ [COMPATIBLE_WIDTHS_RULES_SIZE] = -+ { -+ { "Arial Unicode MS", 12, "Regular Class", 'm' }, -+ { "Arial Unicode MS", 14, "Regular Class", 'm' }, -+ { "Arial", 10, "Regular Class", L'ш' }, -+ { "Arial", 11, "Regular Class", 'm' }, -+ { "Arial", 12, "Regular Class", 'm' }, -+ { "Arial", 12, "Regular Class", L'ш' }, -+ { "Arial", 13, "Regular Class", L'ш' }, -+ { "Arial", 14, "Regular Class", 'm' }, -+ { "Arial", 14, "Regular Class", L'ш' }, -+ { "Arial", 15, "Regular Class", L'ш' }, -+ { "Arial", 17, "Regular Class", 'm' }, -+ { "DejaVu Sans", 15, "Regular Class", 0 }, -+ { "Microsoft Sans Serif", 11, "Regular Class", 0 }, -+ { "Microsoft Sans Serif", 12, "Regular Class", 0 }, -+ { "Segoe UI", 11, "Regular Class", 0 }, -+ { "Segoe UI", 12, "Regular Class", 'm' }, -+ { "Segoe UI", 14, "Regular Class", 'm' }, -+ { "Tahoma", 11, "Regular Class", 0 }, -+ { "Times New Roman", 16, "Regular Class", 'c' }, -+ { "Times New Roman", 16, "Regular Class", 'm' }, -+ { "Times New Roman", 16, "Regular Class", 'o' }, -+ { "Times New Roman", 16, "Regular Class", 'w' }, -+ { "Trebuchet MS", 12, "Regular Class", 0 }, -+ { "Trebuchet MS", 14, "Regular Class", 0 }, -+ { "Trebuchet MS", 15, "Regular Class", 0 }, -+ { "Ubuntu", 12, "Regular Class", 'm' }, -+ { "Verdana", 10, "Regular Class", L'ш' }, -+ { "Verdana", 11, "Regular Class", L'ш' }, -+ { "Verdana and Clones", 12, "Regular Class", 'm' }, -+ { "Verdana and Clones", 12, "Regular Class", 'l' }, -+ { "Verdana and Clones", 12, "Regular Class", 'i' }, -+ { "Verdana and Clones", 12, "Regular Class", 'j' }, -+ { "Verdana and Clones", 13, "Regular Class", 'l' }, -+ { "Verdana and Clones", 13, "Regular Class", 'i' }, -+ { "Verdana and Clones", 13, "Regular Class", 'j' }, -+ { "Verdana and Clones", 14, "Regular Class", 'm' }, -+ }; -+ -+ -+ /* Scaling slightly in the x-direction prior to hinting results in */ -+ /* more visually pleasing glyphs in certain cases. */ -+ /* This sometimes needs to be coordinated with compatible width rules. */ -+#define X_SCALING_RULES_SIZE 40 -+ SPH_ScaleRule X_SCALING_Rules -+ [X_SCALING_RULES_SIZE] = -+ { -+ { "DejaVu Sans", 12, "Regular Class", 'm', .95 }, -+ { "Verdana and Clones", 12, "Regular Class", 'a', 1.1 }, -+ { "Arial", 11, "Regular Class", 'm', .975 }, -+ { "Arial", 12, "Regular Class", 'm', 1.05 }, -+ { "Arial", 13, "Regular Class", L'л', .95 }, -+ { "Arial", 14, "Regular Class", 'm', .95 }, -+ { "Arial", 15, "Regular Class", L'л', .925 }, -+ { "Bitstream Vera Sans", 10, "Regular Class", 0, 1.1 }, -+ { "Bitstream Vera Sans", 12, "Regular Class", 0, 1.05}, -+ { "Bitstream Vera Sans", 16, "Regular Class", 0, 1.05 }, -+ { "Bitstream Vera Sans", 9, "Regular Class", 0, 1.05}, -+ { "DejaVu Sans", 12, "Regular Class", 'l', .975 }, -+ { "DejaVu Sans", 12, "Regular Class", 'i', .975 }, -+ { "DejaVu Sans", 12, "Regular Class", 'j', .975 }, -+ { "DejaVu Sans", 13, "Regular Class", 'l', .95 }, -+ { "DejaVu Sans", 13, "Regular Class", 'i', .95 }, -+ { "DejaVu Sans", 13, "Regular Class", 'j', .95 }, -+ { "DejaVu Sans", 10, "Regular Class", 0, 1.1 }, -+ { "DejaVu Sans", 12, "Regular Class", 0, 1.05 }, -+ { "Georgia", 10, "", 0, 1.05 }, -+ { "Georgia", 11, "", 0, 1.1 }, -+ { "Georgia", 12, "", 0, 1.025 }, -+ { "Georgia", 13, "", 0, 1.05 }, -+ { "Georgia", 16, "", 0, 1.05 }, -+ { "Georgia", 17, "", 0, 1.03 }, -+ { "Liberation Sans", 12, "Regular Class", 'm', 1.1 }, -+ { "Lucida Grande", 11, "Regular Class", 'm', 1.1 }, -+ { "Microsoft Sans Serif", 11, "Regular Class", 'm', .95 }, -+ { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1.05 }, -+ { "Segoe UI", 12, "Regular Class", 'H', 1.05 }, -+ { "Segoe UI", 12, "Regular Class", 'm', 1.05 }, -+ { "Segoe UI", 14, "Regular Class", 'm', 1.05 }, -+ { "Tahoma", 11, "Regular Class", 'm', .975 }, -+ { "Verdana", 10, "Regular Class", 0, 1.1 }, -+ { "Verdana", 12, "Regular Class", 'm', .975 }, -+ { "Verdana", 12, "Regular Class", 0, 1.05 }, -+ { "Verdana", 16, "Regular Class", 0, 1.05 }, -+ { "Verdana", 9, "Regular Class", 0, 1.05 }, -+ { "Times New Roman", 16, "Regular Class", 'm', .95 }, -+ { "Trebuchet MS", 12, "Regular Class", 'm', .95 }, -+ }; -+#else -+#define COMPATIBLE_WIDTHS_RULES_SIZE 1 -+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules -+ [COMPATIBLE_WIDTHS_RULES_SIZE] = -+ { -+ { "-", 0, "", 0 }, -+ }; -+ -+#define X_SCALING_RULES_SIZE 1 -+ SPH_ScaleRule X_SCALING_Rules -+ [X_SCALING_RULES_SIZE] = -+ { -+ { "-", 0, "", 0, 1.0 }, -+ }; -+#endif /* FORCE_NATURAL_WIDTHS */ -+ -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+ -+#endif /* __TTSUBPIX_H__ */ -+ -+/* END */ diff --git a/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch b/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch deleted file mode 100644 index a9aaea1..0000000 --- a/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/include/freetype/config/ftoption.h freetype-subpixel-enabled/include/freetype/config/ftoption.h ---- freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500 -+++ freetype-subpixel-enabled/include/freetype/config/ftoption.h 2012-06-15 07:32:18.144747500 -0500 -@@ -92,7 +92,7 @@ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ - /* */ --/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ -+#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - - /*************************************************************************/ -@@ -577,7 +577,7 @@ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ --/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING - - - /*************************************************************************/ diff --git a/media-libs/freetype/files/freetype-entire-infinality-patchset.patch b/media-libs/freetype/files/freetype-entire-infinality-patchset.patch deleted file mode 100644 index fcb039e..0000000 --- a/media-libs/freetype/files/freetype-entire-infinality-patchset.patch +++ /dev/null @@ -1,4630 +0,0 @@ -freetype-entire-infinality-patchset-20120615-01.patch -------------------------------------------------------------------- -(excludes the TT subpixel patches, which are required ) - -This should patch to a subpixel-patched Freetype 2.4.10. Additional -required files are also contained in the zipfile here: - -http://www.infinality.net/blog/infinality-freetype-patches/ - -You will need to include this file in your profile with something like: - /etd/profile.d/infinality-settings.sh - -You'll need a file named (for 64 bit) -/etc/ld.so.conf.d/freetype-infinality-x86_64.conf that contains: -/usr/lib64/freetype-infinality - -Or a file named (for 32 bit) -/etc/ld.so.conf.d/freetype-infinality-i386.conf that contains: -/usr/lib/freetype-infinality - -Please see each file for more detailed information. - -If you are using this patch, you should also use the fontconfig configuration -also found at the above link. - -The fedora packages I provide take care of all this for you. - - - -DISCLAIMERS: - -This patch will almost certainly result in a performance hit when -freetype is rendering the glyphs. The good news is that fontconfig -caches the glyphs so it's only the first time they are displayed that there -could be a performance issue. - -I expect that if you compile freetype with this patch along with my -TT subpixel hinting patch, you will have a complete build that works the -way I expect it to. However, I have not tested all compile configurations -for errors. I intend to at some point. This patch may make your system crash, -have memory leaks, not compile, or render fonts in a way that you don't like. -Either way, when you use this patch, you should recognize that it -is ALPHA / BETA quality. That said, I intend to run these patches on my -personal system, so they had better be pretty stable! - - - -Changes for 2012-06-15: - -Infinality autohint patches: - * Fix the forced slight hinting logic - * Enhance artificial emboldening at larger ppems - -Infinality subpixel patches: - * Substantial simplification of the TT rules, which helps with all the rest of the following improvements. - * Preparation for submission into Freetype tree. - * Update to Freetype 2.4.10 - * Fix Ubuntu S M N - * Courier fixes - * Make all fonts use standard (non-subpixel) TT hinting for characters '>' and '<'. - * Marked improvement on many non-Latin fonts, including Meiryo. - * Fix Oxygen rendering if usint TT hinting, and other ttfautohinted fonts - * Code cleanup - -Infinality Fontconfig Package: - * Add more fonts to the TT hinted list - * Fixes for font alias (thanks Yegorius) - - -Changes for 2012-04-03: - -Fixes: - - * Get rid of TT_CONFIG_OPTION_SUBPIXEL_HINTING_ADDITIONAL_TWEAKS - and do this by default if TT_CONFIG_OPTION_SUBPIXEL_HINTING is enabled. - * Update to Freetype 2.4.9 - * Fix sdl_ttf rendering - * Code cleanup - * Prevent crashes in OSX mode (thanks Markser) - - -Changes for 2011-12-23: - -Fixes / Tweaks: - * Courier New Hack for '2'. - * Tweak Arial 16px a bit. - * Various tweaks on Courier New, Times NR, Arial, Verdana and others that - create a general improvement in appearance at certain ppems. - * Fixes on some Cyrillic glyphs. - * Pragmata Pro and Pragmata added to patches. - * Be a little more conservative in the way "known settings" of fonts are done. - * Many small improvements to the subpixel hinting patch. - * Fix a crasher in the Windows sharpening algorithm. - * Noticible improvement on spacing in Tahoma 11px, Arial 11px, and other Arial - clones. Me likey. - * Code fixes to prevent some warnings and possible crashes. (Thanks banta) - * Fix Opera and Firefox crashes. slot->face->style_name and - slot->face->family_name need to be checked for not NULL before using. - - -Changes for 2011-11-17: - -Features: - * Added a post-render, pre-lcd-filter filter that attempts to duplicate windows - sharpness / graininess. Controlled by - INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH. - * Added a fringe filter, intended mostly for autohint (but still effective - for certain cases of TT hinting). This attempts to remove gray fringes that - sometimes occur on horizontal stems and angled serifs and doodads - (Times, Segoe '1', etc.) - * Added a grayscale filter. - * Added brightness/contrast filter. - * Substantial improvements in the stem alignment algorithm! Wow! - * Stem alignment now also happens on grayscale antialiased fonts (rgba=none). - -Fixes / Tweaks: - * Changes inside of local.conf, which are documented there. - * Removed an artificial shift of 1/8 pixel to the right on stem aligned glyphs - which should result in sharper looking alignment. - * Added XFT_SETTINGS into infinality-settings.sh. This means it will require - less configuration on the end-user side. - * Fixed code to not touch bold, thin, narrow or italic faces for scale or - alignment (until they can be properly accounted for). - * Added -lm dependency to the code again. (It seems to sneak off now and then) - * Changed autohinter horizontal stem stem snapping from on/off to use a value - between 0 and 100. - * Functions getenv() and system() were crashing evince in _lcd_stem_align() - at odd times. A workaround has been put in place. - * Moved _lcd_stem_align and all other filters into ftsmooth.c, which is a better place. - * Use malloc() in _lcd_stem_align for allocating structs and arrays of structs - instead of what I learned in C++ class 10+ years ago. Should prevent abiword - from crashing with large pt sizes like 3000. (A workaround has been put - in place to automatically skip alignment on any ppem > 100. This will - prevent the crashes until the real solution can be figured out.) - * Fix some compiler warnings. Some are still present. - * Added "m" control to alignment algorithm. This will cause all stems to m - (or other 3-pronged glyphs) to get aligned to pixels. It still needs a bit - of work, as it makes the best looking glyph size change. This is because - the glyph now needs to snap stems to only even or odd pixels, not single ones. - * Added rules to allow "compatible widths" (i.e. widths if the font were being - bitmap TT hinted) on a glyph by glyph basis and tweaked certain fonts like - arial, verdana, times new roman, segoe ui, and trebuchet to use them. - * Don't stem align anything below 9 ppem because it is not consistently good. - * When doing stem alignment, automatically align stems to center of pixel or - start of pixel when necessary. When horizontal stems start snapping to 2 px, - so should the vertical ones in order for it to look nice. - * A Verdana 12 hack to make it render more like Windows. This notoriously - poor looking ppem now looks as good as Verdana 13 without needing fontconfig - replacement. - * Courier New now looks good, and possibly better than Windows rendering, with - TT or autohint rendering. By the way, the hinters of Courier New should - either be commended or executed. - * Improvements in overshoot artifact and fringe correction- Freesans at large - ppem looks nice now. Overshoots on letters like 6, g, s, 3, etc. will - now be rounded to integer pixels. - * Wrap all infinality code within a macro that is set in ftoption.h: - #ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET. Makes it easier to identify - in the code and allows for easy compliation with or without the patches set. - * Variable renaming for more clarity, in code and in environment variables. - * Move stretching code into Freetype instead of relying on programs to handle - fontconfig matrix (they SUCK at it... *cough* Chrome *cough*). - * Additional modifications to the TT subpixel rendering rules for corrections - to Georgia, DejaVu Sans, Times New Roman, Courier New and a couple others. - * A general improvement in the way autohinted fonts render, particularly on - ones that normally look fragile or thin. Examples include Optima, Freemono, - Freeserif, Raleway, MgOpen, etc. I'm doing what Windows does, which is - brightness/contrast adjustment, except you don't see rainbows. - - -Changes for 2011-06-04: - MISSING - - ==================================================================== - ============= ANYTHING BELOW HERE MAY BE INACCURATE NOW ============ - ==================================================================== - -Changes for 2010-11-14: - * Rule tweaks on various fonts. Fixed the Cyrillic y issue and e issue - with Trebuchet, and the ^ issue with Arial. Other issues - (firefox and @font-face) are still present to a degree. - - * A couple new rules to deal with various issues. (work in progress) - - * Additional commenting. - - * Some cleanup of obsolete code. - - * Added some debugging code for potential future enhancements. Please - ignore the mess. - - -Changes for 2010-10-22: - * I'm refocusing on just getting the subpixel looking nice, so I've stripped - back the rendering modes to just 2. The standard SUBPIXEL_HINTING and - the ADDITIONAL_TWEAKS. The rules structure is still in place. I recommend - using ADDITIONAL_TWEAKS mode. - - * Fixed an issue with monochrome rendering that made fonts look really bad. - There is still an issue with them, but they are at least tolerable to - look at now. - - * Added some testing code for detecting inline delta functions. Not sure - if this is useful yet. - - * Added more rules to deal with certain artifacts on various fonts, like the - issue with < > and ^. Created some "exception" rules for certain rules. - - * Reverted back to older rounding functions. The new experimental ones I - was trying were causing artifacts on some fonts. - - * Some code cleanup. - - -Changes for 2010-10-08: - * Fix PDF crashes. - -Changes for 2010-10-04: - * Update to freetype-2.4.3 - - -Changes for 2010-10-03: - * There are lots of changes for this one, some big, some small, and some - that still are not implemented. Not sure if I can remember them all - but I will try! THIS IS A POINT RELEASE THAT IS NOT - INTENDED TO WORK 100%. Some fonts and compile options may be broken - and the code may be inefficient and/or not syntactiacally correct. - That said, I do plan on using this on my system right away. - - * There are now "rendering modes" for the subpixel hinting, with the idea - that this will enventually be able to be controlled by fontconfig. The 4 - modes of enhanced hinting defined so far are: - 1) NATIVE HINTING - this is what freetype TT interpreter does by default. - 2) FIXED NATIVE HINTING - A slighly tweaked version of the above that - does "better" native rendering when displaying on LCD, for those - that still seem to like incorrect, thin fonts, which were only ever - there due to technical limitations. - 3) SUBPIXEL OPTIMIZED HINTING - this is straight up subpixel hinting with - very few tweaks. Just enough to get it working. - 4) COMPATIBILITY MODE HINTING - this is the sweet spot I'm working on - that will hopefully supplant #3 because it will work so well with all - fonts. The idea here is to tweak all available fonts so that each - renders well. - All of these modes either turn on or off switches in the interpreter - to make the fonts render properly for each mode. Right now these are only - compile-time options. - - * Subpixel-related code has been broken out into its own files, so as to not - clutter up the existing code. - - * The rasterizer now pays attention to the additional bits of MS rasterizer - v. 37, meaning that it can now indicate to fonts that it can handle - subpixel rendering. - - * The rounding functions have been adapted to accept a grid resolution - variable, which lets them work on pixel and subpixel boundaries - automatically. Y still needs to be implemented. - - * Additional conditions have been added to the switches, to further refine - how they are applied to different fonts. - - * What all this means qualitatively is that legacy fonts now render much - better. There are still some that need a bit of love, like Courier New. - - - Courier New has some fixes, and some breakage (Ghost pixels above bold - fonts, too thin on regular font) - - Times New Roman has some fixes and breakage (serifs, particularly) - - Tahoma and Trebuchet MS have been cleaned up - - Arial now snaps to grid better, but that causes breakage on a few glyphs - - Verdana 13 is now set to grid fit, but some glyhs are broken (mwxyz) - - Geneva and Geneva CY no longer look like turds - - Lucida Sans Unicode now looks arguably better than Lucida Grande - - - -Changes for 2010-09-16: - - * The changes from 2010-09-14 regarding subpixel when LIGHT hinting enabled - have been reverted due to problems. The old behavior is back. - - * Disable grayscale when subpixel is enabled. This results in better - behavior of some TT instructions within some fonts, like Times New Roman. - - * Some modification of the tweaks, in light of above. - - -Changes for 2010-09-14: - - /************************** NO LONGER IN PLACE *****************************/ - * Subpixel hinting is now used when the LIGHT hinting method and the TT - hinting is called. If FULL hinting is requested it will do the usual - behavior of the TT hinter. - - This allows for all previously existing behavior, plus the new subpixel - hinting behavior, all in the same compile, and it makes sense in that - the slight hinting of the autohinter is essentially doing the same thing - as this, which is not forcing X-direction hints. - - Previously, even if TT was selected, but LIGHT hinting was used, the - autohinter would still be forced. Other than this, autohint is not affected. - /***************************************************************************/ - - * Added a couple more conditionals around things to test whether subpixel - hinting is enabled. There were a few missing that ended up causing some - goofy hinting if subpixel was not enabled, but compiled in. - - - -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/configure freetype-work/configure ---- freetype-subpixel/configure 2011-12-02 13:21:55.000000000 -0600 -+++ freetype-work/configure 2012-06-15 07:42:34.983820793 -0500 -@@ -13,6 +13,8 @@ - # Call the `configure' script located in `builds/unix'. - # - -+export LDFLAGS="$LDFLAGS -lm" -+ - rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk - - if test "x$GNUMAKE" = x; then -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/devel/ftoption.h freetype-work/devel/ftoption.h ---- freetype-subpixel/devel/ftoption.h 2012-06-15 07:31:12.119986648 -0500 -+++ freetype-work/devel/ftoption.h 2012-06-15 17:21:09.266008295 -0500 -@@ -577,6 +577,17 @@ - - /*************************************************************************/ - /* */ -+ /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */ -+ /* all additional infinality patches, which are configured via env */ -+ /* variables. */ -+ /* */ -+ /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */ -+ /* defined. */ -+ /* */ -+#define FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ -+ /*************************************************************************/ -+ /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/include/freetype/config/ftoption.h freetype-work/include/freetype/config/ftoption.h ---- freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500 -+++ freetype-work/include/freetype/config/ftoption.h 2012-06-15 17:21:08.490034299 -0500 -@@ -577,6 +577,17 @@ - - /*************************************************************************/ - /* */ -+ /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */ -+ /* all additional infinality patches, which are configured via env */ -+ /* variables. */ -+ /* */ -+ /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */ -+ /* defined. */ -+ /* */ -+#define FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ -+ /*************************************************************************/ -+ /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/autofit/aflatin.c freetype-work/src/autofit/aflatin.c ---- freetype-subpixel/src/autofit/aflatin.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-work/src/autofit/aflatin.c 2012-06-15 07:42:35.021819509 -0500 -@@ -22,6 +22,7 @@ - - #include "aflatin.h" - #include "aferrors.h" -+#include "strings.h" - - - #ifdef AF_CONFIG_OPTION_USE_WARPER -@@ -528,7 +529,30 @@ - FT_Pos delta; - AF_LatinAxis axis; - FT_UInt nn; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ int checked_adjust_heights_env = 0; -+ FT_Bool adjust_heights = FALSE; - -+ if ( checked_adjust_heights_env == 0 ) -+ { -+ char *adjust_heights_env = getenv( "INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS" ); -+ if ( adjust_heights_env != NULL ) -+ { -+ if ( strcasecmp(adjust_heights_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(adjust_heights_env, "true") == 0) -+ adjust_heights = TRUE; -+ else if ( strcasecmp(adjust_heights_env, "1") == 0) -+ adjust_heights = TRUE; -+ else if ( strcasecmp(adjust_heights_env, "on") == 0) -+ adjust_heights = TRUE; -+ else if ( strcasecmp(adjust_heights_env, "yes") == 0) -+ adjust_heights = TRUE; -+ } -+ } -+ checked_adjust_heights_env = 1; -+ } -+#endif - - if ( dim == AF_DIMENSION_HORZ ) - { -@@ -556,7 +580,7 @@ - { - AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT]; - AF_LatinBlue blue = NULL; -- -+ int threshold = 40; - - for ( nn = 0; nn < Axis->blue_count; nn++ ) - { -@@ -566,12 +590,16 @@ - break; - } - } -- -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( adjust_heights -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15 -+ && metrics->root.scaler.face->size->metrics.x_ppem > 5 ) -+ threshold = 52; -+#endif - if ( blue ) - { - FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); -- FT_Pos fitted = ( scaled + 40 ) & ~63; -- -+ FT_Pos fitted = ( scaled + threshold ) & ~63; - - if ( scaled != fitted ) - { -@@ -626,7 +654,6 @@ - AF_LatinBlue blue = &axis->blues[nn]; - FT_Pos dist; - -- - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; - blue->ref.fit = blue->ref.cur; - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; -@@ -635,7 +662,12 @@ - - /* a blue zone is only active if it is less than 3/4 pixels tall */ - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); -+ -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ /* Do always, in order to prevent fringes */ -+#else - if ( dist <= 48 && dist >= -48 ) -+#endif - { - #if 0 - FT_Pos delta1; -@@ -686,7 +718,12 @@ - delta2 = -delta2; - - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur ); -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ /* Round to prevent fringes */ -+ blue->shoot.fit = FT_PIX_ROUND( blue->ref.fit - delta2 ); -+#else - blue->shoot.fit = blue->ref.fit - delta2; -+#endif - - #endif - -@@ -1433,6 +1470,8 @@ - if ( dist < 0 ) - dist = -dist; - -+ /* round down to pixels */ -+ /*dist = FT_MulFix( dist, scale ) & ~63;*/ - dist = FT_MulFix( dist, scale ); - if ( dist < best_dist ) - { -@@ -1595,20 +1634,95 @@ - FT_Pos dist = width; - FT_Int sign = 0; - FT_Int vertical = ( dim == AF_DIMENSION_VERT ); -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ FT_Int infinality_dist = 0; - - -- if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || -- axis->extra_light ) -- return width; -+ -+ FT_UInt autohint_snap_stem_height = 0; -+ FT_UInt checked_autohint_snap_stem_height = 0; -+ -+ if ( checked_autohint_snap_stem_height == 0) -+ { -+ char *autohint_snap_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT" ); -+ if ( autohint_snap_stem_height_env != NULL ) -+ { -+ sscanf ( autohint_snap_stem_height_env, "%u", &autohint_snap_stem_height ); -+ if (autohint_snap_stem_height > 100 ) autohint_snap_stem_height = 100; -+ else if (autohint_snap_stem_height < 0 ) autohint_snap_stem_height = 0; -+ } -+ checked_autohint_snap_stem_height = 1; -+ } -+ -+ if ( autohint_snap_stem_height == 0 ) -+#endif -+ if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) || -+ axis->extra_light ) -+ return width; - - if ( dist < 0 ) - { - dist = -width; - sign = 1; - } -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ /* Calculate snap value differently than standard freetype */ -+ if ( /* stem_snap_light*/ autohint_snap_stem_height > 0 -+ && ( -+ ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) -+ || ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) ) -+ { -+ infinality_dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); -+ -+ if ( metrics->root.scaler.face->size->metrics.x_ppem > 9 -+ && axis->width_count > 0 -+ && abs ( axis->widths[0].cur - infinality_dist ) < 32 -+ && axis->widths[0].cur > 52 ) -+ { -+ if ( strstr(metrics->root.scaler.face->style_name, "Regular") -+ || strstr(metrics->root.scaler.face->style_name, "Book") -+ || strstr(metrics->root.scaler.face->style_name, "Medium") -+ || strcmp(metrics->root.scaler.face->style_name, "Italic") == 0 -+ || strcmp(metrics->root.scaler.face->style_name, "Oblique") == 0 ) -+ { -+ /* regular weight */ -+ if ( axis->widths[0].cur < 64 ) infinality_dist = 64 ; -+ else if (axis->widths[0].cur < 88) infinality_dist = 64; -+ else if (axis->widths[0].cur < 160) infinality_dist = 128; -+ else if (axis->widths[0].cur < 240) infinality_dist = 190; -+ else infinality_dist = ( infinality_dist ) & ~63; -+ } -+ else -+ { -+ /* bold gets a different threshold */ -+ if ( axis->widths[0].cur < 64 ) infinality_dist = 64 ; -+ else if (axis->widths[0].cur < 108) infinality_dist = 64; -+ else if (axis->widths[0].cur < 160) infinality_dist = 128; -+ else if (axis->widths[0].cur < 222) infinality_dist = 190; -+ else if (axis->widths[0].cur < 288) infinality_dist = 254; -+ else infinality_dist = ( infinality_dist + 16 ) & ~63; -+ } -+ -+ } -+ if (infinality_dist < 52) -+ { -+ if (metrics->root.scaler.face->size->metrics.x_ppem < 9 ) -+ { -+ -+ if (infinality_dist < 32) infinality_dist = 32; -+ } -+ else -+ infinality_dist = 64; -+ } -+ } -+ else if ( autohint_snap_stem_height < 100 -+ && (( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || -+ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) ) -+#else - -- if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || -- ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) -+ if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || -+ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) -+#endif - { - /* smooth hinting process: very lightly quantize the stem width */ - -@@ -1667,7 +1781,10 @@ - dist = ( dist + 32 ) & ~63; - } - } -- else -+ else -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( autohint_snap_stem_height < 100 ) -+#endif - { - /* strong hinting process: snap the stem width to integer pixels */ - -@@ -1675,7 +1792,9 @@ - - - dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); -- -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( autohint_snap_stem_height > 0 ) goto Done_Width; -+#endif - if ( vertical ) - { - /* in the case of vertical hinting, always round */ -@@ -1738,6 +1857,23 @@ - } - - Done_Width: -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if (axis->widths[0].cur > 42 ) -+ /* weighted average */ -+ dist = (dist * (100 - autohint_snap_stem_height) + infinality_dist * autohint_snap_stem_height ) / 100; -+ -+ { -+ int factor = 100; -+ if (axis->standard_width < 100) -+ factor = axis->standard_width; -+ -+ if (metrics->root.scaler.face->size->metrics.x_ppem >=9 && dist < 52 ) dist += ((52 - dist) * factor) / 100; -+ if (metrics->root.scaler.face->size->metrics.x_ppem <9 && dist < 32 ) dist += ((32 - dist) * factor) / 100; -+ -+ if (axis->standard_width > 100 && metrics->root.scaler.face->size->metrics.x_ppem >=11 && dist < 64 ) dist = 64; -+ if (axis->standard_width > 100 && metrics->root.scaler.face->size->metrics.x_ppem >=9 && dist < 52 ) dist = 52; -+ } -+#endif - if ( sign ) - dist = -dist; - -@@ -1760,6 +1896,8 @@ - (AF_Edge_Flags)base_edge->flags, - (AF_Edge_Flags)stem_edge->flags ); - -+/* if fitted_width causes stem_edge->pos to land basically on top of an existing -+ * stem_edge->pos, then add or remove 64. Need to figure out a way to do this */ - - stem_edge->pos = base_edge->pos + fitted_width; - -@@ -2234,8 +2372,32 @@ - { - FT_Error error; - int dim; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ int emboldening_strength = 0; - -+ int checked_use_various_tweaks_env = 0; -+ FT_Bool use_various_tweaks = FALSE; - -+ if ( checked_use_various_tweaks_env == 0 ) -+ { -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); -+ if ( use_various_tweaks_env != NULL ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) -+ use_various_tweaks = TRUE; -+ } -+ } -+ checked_use_various_tweaks_env = 1; -+ } -+#endif - error = af_glyph_hints_reload( hints, outline ); - if ( error ) - goto Exit; -@@ -2292,7 +2454,54 @@ - } - } - af_glyph_hints_save( hints, outline ); -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+#if 0 -+ if( metrics->root.scaler.face->style_name ) -+ { -+ if ( strcasestr(metrics->root.scaler.face->style_name, "Bold") -+ || strcasestr(metrics->root.scaler.face->style_name, "Black") -+ || strcasestr(metrics->root.scaler.face->style_name, "Narrow") -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15 -+ || strcasestr(metrics->root.scaler.face->style_name, "Condensed") -+ && metrics->root.scaler.face->size->metrics.x_ppem < 20 ) -+ goto Exit; -+ } -+ if( metrics->root.scaler.face->family_name ) -+ { -+ if ( strcasestr(metrics->root.scaler.face->family_name, "Bold") -+ || strcasestr(metrics->root.scaler.face->family_name, "Black") -+ || strcasestr(metrics->root.scaler.face->family_name, "Narrow") -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15 -+ || strcasestr(metrics->root.scaler.face->family_name, "Condensed") -+ && metrics->root.scaler.face->size->metrics.x_ppem < 20 ) -+ goto Exit; -+ } - -+ /* if the font is particularly thin, embolden it, up to 1 px */ -+ if ( use_various_tweaks -+ && metrics->axis->widths[0].cur <= FT_MulDiv ( autohint_minimum_stem_width, 64, 100) -+ && !( dim == AF_DIMENSION_VERT ) -+ && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) -+ { -+ if ( metrics->axis->widths[0].cur -+ / metrics->root.scaler.face->size->metrics.x_ppem < 5 ) -+ { -+ emboldening_strength = FT_MulDiv ( autohint_minimum_stem_width, 64, 100) - metrics->axis->widths[0].cur; -+ if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 ) -+ emboldening_strength -= 10; -+ if ( metrics->root.scaler.face->size->metrics.x_ppem < 7 ) -+ emboldening_strength -= 10; -+ } -+ if ( emboldening_strength < 0 ) emboldening_strength = 0; -+ FT_Outline_Embolden(outline,emboldening_strength); -+ } -+#endif -+ /* Save this width for use in ftsmooth.c. This is a shameful hack */ -+ const char* c1 = "CUR_WIDTH"; -+ char c2[8]; -+ snprintf(c2,8,"%ld",metrics->axis->widths[0].cur); -+ setenv(c1, c2, 1); -+#endif - Exit: - return error; - } -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftlcdfil.c freetype-work/src/base/ftlcdfil.c ---- freetype-subpixel/src/base/ftlcdfil.c 2010-04-01 03:18:57.000000000 -0500 -+++ freetype-work/src/base/ftlcdfil.c 2012-06-15 07:42:35.022819476 -0500 -@@ -21,6 +21,9 @@ - #include FT_IMAGE_H - #include FT_INTERNAL_OBJECTS_H - -+#include <math.h> -+#include <string.h> -+#include <strings.h> - - #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - -@@ -287,10 +290,51 @@ - { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* the values here sum up to a value larger than 256, */ - /* providing a cheap gamma correction */ -- static const FT_Byte default_filter[5] = -+ static FT_Byte default_filter[5] = - { 0x10, 0x40, 0x70, 0x40, 0x10 }; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ int checked_filter_params_env = 0; - -+ if ( checked_filter_params_env == 0 ) -+ { -+ char *filter_params = getenv( "INFINALITY_FT_FILTER_PARAMS" ); -+ if ( filter_params != NULL && strcmp(filter_params, "") != 0 ) -+ { -+ float f1, f2, f3, f4, f5; -+ -+ if ( strcasecmp(filter_params, "default" ) != 0) -+ { -+ int args_assigned = 0; -+ args_assigned = sscanf ( filter_params, "%f %f %f %f %f", &f1, &f2, &f3, &f4, &f5 ); - -+ if ( args_assigned == 5 ) -+ { -+ if ( f1 + f2 + f3 + f4 + f5 > 5 ) -+ { -+ /* Assume we were given integers instead of floats */ -+ /* 0 to 100 */ -+ default_filter[0] = (FT_Byte) (f1 * 2.55f + 0.5f); -+ default_filter[1] = (FT_Byte) (f2 * 2.55f + 0.5f); -+ default_filter[2] = (FT_Byte) (f3 * 2.55f + 0.5f); -+ default_filter[3] = (FT_Byte) (f4 * 2.55f + 0.5f); -+ default_filter[4] = (FT_Byte) (f5 * 2.55f + 0.5f); -+ } -+ else -+ { -+ /* Assume we were given floating point values */ -+ /* 0 to 1.0 */ -+ default_filter[0] = (FT_Byte) (f1 * 255.0f + 0.5f); -+ default_filter[1] = (FT_Byte) (f2 * 255.0f + 0.5f); -+ default_filter[2] = (FT_Byte) (f3 * 255.0f + 0.5f); -+ default_filter[3] = (FT_Byte) (f4 * 255.0f + 0.5f); -+ default_filter[4] = (FT_Byte) (f5 * 255.0f + 0.5f); -+ } -+ } -+ } -+ } -+ checked_filter_params_env = 1; -+ } -+#endif - if ( !library ) - return FT_Err_Invalid_Argument; - -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftobjs.c freetype-work/src/base/ftobjs.c ---- freetype-subpixel/src/base/ftobjs.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-work/src/base/ftobjs.c 2012-06-15 07:42:35.025819374 -0500 -@@ -513,6 +513,22 @@ - ft_lookup_glyph_renderer( FT_GlyphSlot slot ); - - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ static void -+ ft_glyphslot_enlarge_metrics( FT_GlyphSlot slot, -+ FT_Render_Mode mode ) -+ { -+ FT_Glyph_Metrics* metrics = &slot->metrics; -+ FT_Pos enlarge_cbox = 0; -+ /* enlarge for grayscale rendering */ -+ if ( mode == FT_RENDER_MODE_NORMAL ) enlarge_cbox = 64; -+ -+ metrics->horiBearingX -= enlarge_cbox; -+ metrics->width += 2*enlarge_cbox; -+ } -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ -+ -+ - #ifdef GRID_FIT_METRICS - static void - ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, -@@ -571,8 +587,33 @@ - FT_Bool autohint = FALSE; - FT_Module hinter; - TT_Face ttface = (TT_Face)face; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - -+ int checked_use_various_tweaks_env = FALSE; -+ FT_Bool use_various_tweaks = FALSE; - -+ if ( !checked_use_various_tweaks_env ) -+ { -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); -+ if ( use_various_tweaks_env != NULL ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; -+ } -+ } -+ checked_use_various_tweaks_env = 1; -+ } -+ -+ /* Force autohint if no tt instructions */ -+ if ( use_various_tweaks && -+ ttface->num_locations && -+ ttface->max_profile.maxSizeOfInstructions == 0 ) -+ load_flags |= FT_LOAD_FORCE_AUTOHINT; -+#endif - if ( !face || !face->size || !face->glyph ) - return FT_Err_Invalid_Face_Handle; - -@@ -652,8 +693,18 @@ - if ( autohint ) - { - FT_AutoHinter_Service hinting; -- -- -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( use_various_tweaks ) -+ { -+ /* Force slight hinting over full hinting always */ -+ load_flags &= ~FT_LOAD_TARGET_LCD; -+ load_flags &= ~FT_LOAD_TARGET_LCD_V; -+ load_flags &= ~FT_LOAD_TARGET_MONO; -+ load_flags &= ~FT_LOAD_TARGET_NORMAL; -+ load_flags |= FT_LOAD_TARGET_LIGHT; -+ /*printf("%d ", load_flags);*/ -+ } -+#endif - /* try to load embedded bitmaps first if available */ - /* */ - /* XXX: This is really a temporary hack that should disappear */ -@@ -691,6 +742,10 @@ - } - else - { -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ char* c1 = "CUR_WIDTH"; -+ char* c2 = "0"; -+#endif - error = driver->clazz->load_glyph( slot, - face->size, - glyph_index, -@@ -698,6 +753,16 @@ - if ( error ) - goto Exit; - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ setenv(c1, c2, 1); -+ -+ { -+ /* fix for sdl_ttf */ -+ FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); -+ ft_glyphslot_enlarge_metrics( slot, mode ); -+ } -+#endif -+ - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* check that the loaded outline is correct */ -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftoutln.c freetype-work/src/base/ftoutln.c ---- freetype-subpixel/src/base/ftoutln.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-work/src/base/ftoutln.c 2012-06-15 16:19:12.645429337 -0500 -@@ -897,7 +897,29 @@ - FT_Vector v_prev, v_first, v_next, v_cur; - FT_Int c, n, first; - FT_Int orientation; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ int checked_use_various_tweaks_env = 0; -+ FT_Bool use_various_tweaks = FALSE; - -+ if ( checked_use_various_tweaks_env == 0 ) -+ { -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); -+ if ( use_various_tweaks_env != NULL ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; -+ } -+ } -+ checked_use_various_tweaks_env = 1; -+ } -+ -+ if ( use_various_tweaks ) -+ ystrength = FT_PIX_FLOOR ( ystrength ); -+#endif - - if ( !outline ) - return FT_Err_Invalid_Argument; -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftsynth.c freetype-work/src/base/ftsynth.c ---- freetype-subpixel/src/base/ftsynth.c 2012-06-14 23:26:45.000000000 -0500 -+++ freetype-work/src/base/ftsynth.c 2012-06-15 16:36:20.612600325 -0500 -@@ -88,7 +88,26 @@ - FT_Face face = slot->face; - FT_Error error; - FT_Pos xstr, ystr; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ int checked_use_various_tweaks_env = 0; -+ FT_Bool use_various_tweaks = FALSE; - -+ if ( checked_use_various_tweaks_env == 0 ) -+ { -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); -+ if ( use_various_tweaks_env != NULL ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE; -+ } -+ } -+ checked_use_various_tweaks_env = 1; -+ } -+#endif - - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && - slot->format != FT_GLYPH_FORMAT_BITMAP ) -@@ -101,6 +120,11 @@ - - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( use_various_tweaks ) -+ (void)FT_Outline_EmboldenXY( &slot->outline, xstr, FT_PIX_FLOOR( ystr ) ); -+ else -+#endif - /* ignore error */ - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr ); - } -@@ -141,6 +165,9 @@ - - slot->metrics.width += xstr; - slot->metrics.height += ystr; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ /*if ( !use_various_tweaks ) */ -+#endif - slot->metrics.horiAdvance += xstr; - slot->metrics.vertAdvance += ystr; - -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/smooth/ftsmooth.c freetype-work/src/smooth/ftsmooth.c ---- freetype-subpixel/src/smooth/ftsmooth.c 2012-06-14 00:35:58.000000000 -0500 -+++ freetype-work/src/smooth/ftsmooth.c 2012-06-15 07:42:35.030819204 -0500 -@@ -26,6 +26,16 @@ - - #include "ftsmerrs.h" - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+#include <math.h> -+#include "../../include/freetype/ftbitmap.h" -+#include "strings.h" -+#include "../autofit/aflatin.h" -+#include "../../include/freetype/ftoutln.h" -+ -+#define verbose FALSE -+#define STVALUES if (verbose) printf ("scale:%f translate:%ld ", *scale_value, *translate_value); -+#endif - - /* initialize renderer -- init its raster */ - static FT_Error -@@ -34,65 +44,2822 @@ - FT_Library library = FT_MODULE_LIBRARY( render ); - - -- render->clazz->raster_class->raster_reset( render->raster, -- library->raster_pool, -- library->raster_pool_size ); -+ render->clazz->raster_class->raster_reset( render->raster, -+ library->raster_pool, -+ library->raster_pool_size ); -+ -+ return 0; -+ } -+ -+ -+ /* sets render-specific mode */ -+ static FT_Error -+ ft_smooth_set_mode( FT_Renderer render, -+ FT_ULong mode_tag, -+ FT_Pointer data ) -+ { -+ /* we simply pass it to the raster */ -+ return render->clazz->raster_class->raster_set_mode( render->raster, -+ mode_tag, -+ data ); -+ } -+ -+ /* transform a given glyph image */ -+ static FT_Error -+ ft_smooth_transform( FT_Renderer render, -+ FT_GlyphSlot slot, -+ const FT_Matrix* matrix, -+ const FT_Vector* delta ) -+ { -+ FT_Error error = Smooth_Err_Ok; -+ -+ -+ if ( slot->format != render->glyph_format ) -+ { -+ error = Smooth_Err_Invalid_Argument; -+ goto Exit; -+ } -+ -+ if ( matrix ) -+ FT_Outline_Transform( &slot->outline, matrix ); -+ -+ if ( delta ) -+ FT_Outline_Translate( &slot->outline, delta->x, delta->y ); -+ -+ Exit: -+ return error; -+ } -+ -+ -+ /* return the glyph's control box */ -+ static void -+ ft_smooth_get_cbox( FT_Renderer render, -+ FT_GlyphSlot slot, -+ FT_BBox* cbox ) -+ { -+ FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); -+ -+ if ( slot->format == render->glyph_format ) -+ FT_Outline_Get_CBox( &slot->outline, cbox ); -+ } -+ -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ static FT_Fixed FT_FixedFromFloat(float f) -+ { -+ short value = f; -+ unsigned short fract = (f - value) * 0xFFFF; -+ return (FT_Fixed)((long)value << 16 | (unsigned long)fract); -+ } -+ -+ -+ /* ChromeOS sharpening algorithm */ -+ /* soften the sub-pixel anti-aliasing and sharpen */ -+ static void -+ _ft_lcd_chromeos_sharpen( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_Byte cutoff, -+ double gamma_value ) -+ { -+ static FT_Bool initialized_gamma = FALSE; -+ static unsigned short gamma_ramp[256]; -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ int ii; -+ -+ if (!initialized_gamma) -+ { -+ initialized_gamma = TRUE; -+ /* linear to voltage */ -+ for ( ii = 0; ii < 256; ii++ ) -+ { -+ gamma_ramp[ii] = (unsigned char) -+ ( pow( (double)ii/255.0, gamma_value ) * 255.0f ); -+ if (gamma_ramp[ii] < cutoff) { -+ gamma_ramp[ii] = 0; -+ } -+ } -+ } -+ -+ /* horizontal in-place sub-pixel sharpening filter */ -+ if ( mode == FT_RENDER_MODE_LCD) -+ { -+ FT_Byte* line = bitmap->buffer; -+ for ( ; height > 0; height--, line += bitmap->pitch ) -+ { -+ FT_UInt xx; -+ for ( xx = 0; xx < width; xx++ ) -+ { -+ line[xx] = gamma_ramp[line[xx]]; -+ } -+ } -+ } -+ } -+ -+ /* simple linear scale to handle various sliding values */ -+ float -+ sliding_scale ( int min_value, -+ int max_value, -+ float min_amount, -+ float max_amount, -+ int cur_value ) -+ { -+ -+ float m = (min_amount - max_amount) / (float)(min_value - max_value); -+ float result = (((float)cur_value * m) + (max_amount - max_value * m)) ; -+ -+ if (min_amount < max_amount) -+ { -+ if (result < min_amount) return min_amount; -+ if (result > max_amount) return max_amount; -+ } -+ else -+ { -+ if (result < max_amount) return max_amount; -+ if (result > min_amount) return min_amount; -+ } -+ -+ return result; -+ } -+ -+ -+ /* brightness and contrast adjustment on the bitmap */ -+ static FT_Bool -+ _ft_bitmap_bc ( FT_Bitmap* bitmap, -+ float brightness, -+ float contrast ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ FT_Byte* line = bitmap->buffer; -+ FT_UInt xx; -+ -+ if ( brightness == 0 && contrast == 0 ) return FALSE; -+ -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch ) -+ { -+ for ( xx = 0; xx < width - 1; xx += 1 ) -+ { -+ if ( line[xx] > 0) -+ { -+ float value = (float)(255 - line[xx]) / 256.0; -+ FT_Int result = 0; -+ -+ if (brightness < 0.0) value = value * ( 1.0 + brightness); -+ else value = value + ((1.0 - value) * brightness); -+ value = (value - 0.5) * (tan ((contrast + 1.0) * 3.141592/4.0) ) + 0.5; -+ -+ result = (FT_Int)(255.0 - (value) * 256.0); -+ -+ if (result < 0) result = 0; -+ if (result > 255) result = 255; -+ -+ line[xx] = result; -+ } -+ } -+ } -+ return TRUE; -+ } -+ -+ -+ /* Filter to mimic Windows-style sharpening */ -+ /* Determined via 100% experimentation. */ -+ static void -+ _ft_lcd_windows_sharpen( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_Bitmap new_bitmap; -+ -+ FT_Bitmap_New(&new_bitmap); -+ -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ new_line = (&new_bitmap)->buffer; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ FT_UInt xx, threshold = 128; -+ FT_Byte* prevline = line - bitmap->pitch; -+ FT_Byte* nextline = line + bitmap->pitch; -+ -+ FT_Byte* new_prevline = new_line - bitmap->pitch; -+ FT_Byte* new_nextline = new_line + bitmap->pitch; -+ -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ /* subpixel grid sp11 sp21 sp31 */ -+ /* where sp22 is sp12 sp22 sp32 */ -+ /* current subpixel. sp13 sp23 sp33 */ -+ -+ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff, -+ prevdiff, nextdiff, sp11, sp21, sp31, sp12, sp22, sp32, -+ sp13, sp23, sp33; -+ -+ sp12 = line [xx-1]; -+ sp22 = line [xx]; -+ sp32 = line [xx+1]; -+ -+ if (height == bitmap->rows) -+ { -+ prevtotal = sp11 = sp21 = sp31 = 0; -+ prevdiff = sp22; -+ lefttotal = sp12 + sp13; -+ righttotal = sp32 + sp33; -+ } -+ else -+ { -+ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1]; -+ sp11 = prevline [xx-1]; -+ sp21 = prevline [xx]; -+ sp31 = prevline [xx+1]; -+ prevdiff = sp22 - sp21; -+ lefttotal = sp11 + sp12 + sp13; -+ righttotal = sp31 + sp32 + sp33; -+ } -+ -+ -+ if (height == 1) -+ { -+ nexttotal = sp13 = sp23 = sp33 = 0; -+ nextdiff = sp22; -+ lefttotal = sp11 + sp12; -+ righttotal = sp31 + sp32; -+ } -+ else -+ { -+ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1]; -+ sp13 = nextline [xx-1]; -+ sp23 = nextline [xx]; -+ sp33 = nextline [xx+1]; -+ nextdiff = sp23 - sp22; -+ lefttotal = sp11 + sp12 + sp13; -+ righttotal = sp31 + sp32 + sp33; -+ } -+ -+ sidesdiff = lefttotal - righttotal; -+ if (sidesdiff < 0) sidesdiff *= -1; -+ if (prevdiff < 0) prevdiff *= -1; -+ if (nextdiff < 0) nextdiff *= -1; -+ -+ /* if the current pixel is less than threshold, and greater than 0 */ -+ if ( sp22 <= threshold && sp22 > 0 ) -+ { -+ /* A pixel is horizontally isolated if: */ -+ /* 1: All upper adjecent pixels are >= threshold */ -+ if ( prevtotal >= nexttotal && abs (sp11 - sp12) > 5 && abs (sp21 - sp22) > 5 && abs (sp31 - sp32) > 5 /* not a vert stem end */ -+ && sp11 >= threshold -+ && sp21 >= threshold -+ && sp31 >= threshold && abs (sp23 - sp22) > 15 /* not on a vert stem */ -+ ) -+ { -+ /* darken upper adjacent subpixel; lighten current */ -+ if (height != (FT_UInt)bitmap->rows) new_prevline[xx] += ((255 - new_prevline[xx]) * strength) / 100 ; -+ new_line[xx] -= (new_line[xx] * strength) / 100; -+ -+ if (height != 1 && height != (FT_UInt)bitmap->rows) if (new_nextline[xx] > 155 + (100 - strength)) new_prevline[xx] = 255; -+ -+ } -+ else if ( nexttotal > prevtotal && abs (sp13 - sp12) > 5 && abs (sp23 - sp22) > 5 && abs (sp33 - sp32) > 5 -+ /* 2: All lower adjecent pixels are >= threshold */ -+ && sp13 >= threshold -+ && sp23 >= threshold -+ && sp33 >= threshold && abs (sp22 - sp21) > 15 -+ ) -+ { -+ /* darken lower adjacent subpixel; lighten current */ -+ if (height != 1) new_nextline[xx] += (255 - new_nextline[xx]) * strength / 100 ; -+ new_line[xx] -= (new_line[xx] * strength) / 100; -+ -+ if (height != 1) if (new_nextline[xx] > 155 + (100 - strength)) new_nextline[xx] = 255; -+ -+ } -+ } -+ else if ( sp22 > threshold && sp22 < 255 ) -+ { -+ if ( sp11 <= threshold && abs (sp13 - sp12) > 5 && abs (sp23 - sp22) > 5 && abs (sp33 - sp32) > 5 -+ && sp21 <= threshold -+ && sp31 <= threshold -+ && prevtotal <= nexttotal && abs (sp22 - sp21) > 15 -+ ) -+ { -+ /* bring this subpixel 1/3 of the way to 255 at 100% strength */ -+ new_line[xx] += (strength * (255 - new_line[xx]))/100 ; -+ if (height != (FT_UInt)bitmap->rows) new_prevline[xx] -= (new_prevline[xx] * strength) / 300; -+ } -+ else if ( -+ sp13 <= threshold && abs (sp11 - sp12) > 5 && abs (sp21 - sp22) > 5 && abs (sp31 - sp32) > 5 -+ && sp23 <= threshold -+ && sp33 <= threshold && -+ nexttotal < prevtotal && abs (sp23 - sp22) > 15 -+ -+ ) -+ { -+ new_line[xx] += (strength * (255 - new_line[xx]))/100 ; -+ if (height != 1) new_nextline[xx] -= (new_nextline[xx] * strength) / 300; -+ } -+ } -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ static void -+ _ft_lcd_darken_x ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_Bitmap new_bitmap; -+ -+ int factor1,factor2; -+ int bias = 0; -+ -+ FT_Bitmap_New(&new_bitmap); -+ -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ new_line = (&new_bitmap)->buffer; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ FT_UInt xx; -+ FT_Byte* prevline = line - bitmap->pitch; -+ FT_Byte* nextline = line + bitmap->pitch; -+ -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ /* subpixel grid sp11 sp21 sp31 */ -+ /* where sp22 is sp12 sp22 sp32 */ -+ /* current subpixel. sp13 sp23 sp33 */ -+ -+ FT_Int sp21, sp12, sp22, sp32, sp23; -+ -+ sp12 = line [xx-1]; -+ sp22 = line [xx]; -+ sp32 = line [xx+1]; -+ -+ if (height == bitmap->rows) -+ { -+ sp21 = 0; -+ } -+ else -+ { -+ sp21 = prevline [xx]; -+ } -+ -+ if (height == 1) -+ { -+ sp23 = 0; -+ -+ } -+ else -+ { -+ sp23 = nextline [xx]; -+ } -+ -+ /* darken subpixel if neighbor above and below are much less than */ -+ /* safer but less effective */ -+ factor1 = 5; -+ factor2 = 5; -+ -+ /* make matches in the middle of glyph slightly darker */ -+ /*if (height > 1 && height < (FT_UInt)bitmap->rows) bias = 1;*/ -+ -+ if ( sp22 > factor1 * sp21 && sp22 > factor1 * sp23 && sp22 > factor2 && sp12 > 16 && sp32 > 16 ) -+ if (new_line[xx] < (strength * 255) / 100 ) -+ new_line[xx] = (strength * 255) / 100 + bias * (255 - (strength * 255) / 100) / 3; -+ -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ static void -+ _ft_lcd_darken_y ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_Bitmap new_bitmap; -+ -+ FT_Bitmap_New(&new_bitmap); -+ -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ new_line = (&new_bitmap)->buffer; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ -+ FT_UInt xx; -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ if (line[xx] > line[xx-1] && line[xx] > line[xx+1]) -+ { -+ if (new_line[xx] > 0) new_line[xx] += (strength * (255 - new_line[xx])) / 100; -+ new_line[xx-1] += (strength * (255 - line[xx-1])) / 100; -+ new_line[xx+1] += (strength * (255 - line[xx+1])) / 100; -+ } -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ static void -+ _ft_bitmap_cap ( FT_Bitmap* bitmap, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_UInt cur_value = 0; -+ -+ FT_Bitmap new_bitmap; -+ -+ FT_Bitmap_New(&new_bitmap); -+ -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ new_line = (&new_bitmap)->buffer; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ -+ FT_UInt xx; -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ cur_value = (new_line[xx-1] + new_line[xx] + new_line[xx+1]) / 3; -+ if (cur_value > (strength * 255) / 100 ) -+ { -+ FT_UInt new_factor = (strength * 255) / 100; -+ new_line[xx] = (new_line[xx] * new_factor) / cur_value; -+ new_line[xx+1] = (new_line[xx+1] * new_factor) / cur_value; -+ new_line[xx-1] = (new_line[xx-1] * new_factor) / cur_value; -+ } -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ int -+ gamma2 ( int val, float value ) -+ { -+ return 256 * (1.0 - pow((1.0 - (float)val/ 256.0) , 1.0/value)); -+ } -+ -+ -+ -+ static void -+ _ft_bitmap_embolden ( FT_Bitmap* bitmap, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ FT_Bitmap new_bitmap; -+ FT_UInt xx; -+ -+ FT_Bitmap_New(&new_bitmap); -+ -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ -+ new_line = (&new_bitmap)->buffer; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ -+ FT_Int new_value = 0; -+ -+ new_value = (strength * line [xx-1]) / 100 + gamma2(line [xx], .75) + (strength * line [xx+1]) / 100; -+ if (new_value > 255) new_value = 255; -+ -+ new_line[xx] = new_value; -+ -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ -+ static void -+ _ft_bitmap_gamma ( FT_Bitmap* bitmap, -+ float strength ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_UInt xx; -+ -+ if (strength > 0) -+ for (height = (FT_UInt)bitmap->rows; -+ height > 0; -+ height--, line += bitmap->pitch ) -+ { -+ -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ if (abs(line[xx-1] - line[xx]) < 20 || abs(line[xx+1] - line[xx]) < 20) -+ line [xx] = gamma2(line [xx], strength) ; -+ -+ } -+ -+ } -+ } -+ -+ -+ /* Fringe filter */ -+ static void -+ _ft_lcd_fringe_filter ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ FT_Byte* new_line; -+ FT_Byte* line = bitmap->buffer; -+ -+ FT_Bitmap new_bitmap; -+ FT_Bitmap_New(&new_bitmap); -+ -+ -+ line = bitmap->buffer; -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap); -+ new_line = (&new_bitmap)->buffer; -+ for (height = (FT_UInt)bitmap->rows ; height > 0; height--, line += bitmap->pitch, new_line += bitmap->pitch ) -+ { -+ /* Threshold set to 1/2 pixel intensity */ -+ FT_UInt xx, threshold = 128; -+ -+ /* Hack to make this work when bitmap is at first or last line */ -+ FT_Int fudge = bitmap->pitch * (height == (FT_UInt)bitmap->rows); -+ -+ -+ FT_Byte* prevline = line - bitmap->pitch + fudge; -+ FT_Byte* nextline = line + bitmap->pitch; -+ -+ for ( xx = 1; xx < width - 1; xx += 1 ) -+ { -+ /* subpixel grid sp11 sp21 sp31 */ -+ /* where sp22 is sp12 sp22 sp32 */ -+ /* current subpixel. sp13 sp23 sp33 */ -+ -+ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff, -+ leftdiff, rightdiff, prevdiff, nextdiff, sp11, sp21, sp31, -+ sp12, sp22, sp32, sp13, sp23, sp33; -+ -+ sp12 = line [xx-1]; -+ sp22 = line [xx]; -+ sp32 = line [xx+1]; -+ -+ /* if at max height fake out some values */ -+ if (height == (FT_UInt)bitmap->rows) -+ { -+ prevtotal = sp11 = sp21 = sp31 = 0; -+ prevdiff = sp22; -+ lefttotal = sp12 + sp13; -+ righttotal = sp32 + sp33; -+ } -+ else -+ { -+ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1]; -+ sp11 = prevline [xx-1]; -+ sp21 = prevline [xx]; -+ sp31 = prevline [xx+1]; -+ prevdiff = sp22 - sp21; -+ lefttotal = sp11 + sp12 + sp13; -+ righttotal = sp31 + sp32 + sp33; -+ } -+ -+ /* if at min height fake out some values */ -+ if (height == 1) -+ { -+ nexttotal = sp13 = sp23 = sp33 = 0; -+ nextdiff = sp22; -+ lefttotal = sp11 + sp12; -+ righttotal = sp31 + sp32; -+ } -+ else -+ { -+ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1]; -+ sp13 = nextline [xx-1]; -+ sp23 = nextline [xx]; -+ sp33 = nextline [xx+1]; -+ nextdiff = sp23 - sp22; -+ lefttotal = sp11 + sp12 + sp13; -+ righttotal = sp31 + sp32 + sp33; -+ } -+ -+ sidesdiff = lefttotal - righttotal; -+ leftdiff = sp22 - sp12; -+ rightdiff = sp32 - sp22; -+ if (sidesdiff < 0) sidesdiff *= -1; -+ if (prevdiff < 0) prevdiff *= -1; -+ if (nextdiff < 0) nextdiff *= -1; -+ if (leftdiff < 0) leftdiff *= -1; -+ if (rightdiff < 0) rightdiff *= -1; -+ -+ /* if the current subpixel is less than threshold, and varies only -+ slightly to left or right, lighten it */ -+ if ( sp22 <= threshold && sp22 > 0 && (leftdiff < 10 || rightdiff < 10 ) ) -+ { -+ /* A pixel is horizontally isolated if: */ -+ /* 1: All upper adjecent subpixels are >= threshold and all lower -+ adjacent ones are essentially white */ -+ if ( prevtotal >= nexttotal -+ && sp11 >= threshold -+ && sp21 >= threshold -+ && sp31 >= threshold -+ && sp13 < 2 -+ && sp23 < 2 -+ && sp33 < 2 -+ ) -+ -+ { -+ new_line[xx] -= (new_line[xx] * strength) / 100; -+ if (leftdiff < 10) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ -+ if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */ -+ } -+ else if ( nexttotal > prevtotal -+ /* 2: the inverse of above */ -+ && sp13 >= threshold -+ && sp23 >= threshold -+ && sp33 >= threshold -+ && sp11 < 2 -+ && sp21 < 2 -+ && sp31 < 2 -+ ) -+ { -+ new_line[xx] -= (new_line[xx] * strength) / 100; -+ if (leftdiff < 10) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */ -+ if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */ -+ } -+ } -+ /* otherwise if the current subpixel is more than threshold, and varies -+ slightly to left or right, darken it */ -+ else if ( sp22 > threshold && sp22 < 255 && (leftdiff < 10 || rightdiff < 10 ) ) -+ { -+ if ( sp11 <= 2 -+ && sp21 <= 2 -+ && sp31 <= 2 -+ && sp13 >= threshold -+ && sp23 >= threshold -+ && sp33 >= threshold -+ && -+ prevtotal < nexttotal -+ ) -+ -+ { -+ new_line[xx] += ((255 - new_line[xx]) * strength) / 100; -+ } -+ else if ( -+ sp13 <= 2 -+ && sp23 <= 2 -+ && sp33 <= 2 && -+ nexttotal < prevtotal -+ && sp11 >= threshold -+ && sp21 >= threshold -+ && sp31 >= threshold -+ -+ ) -+ { -+ new_line[xx] += ((255 - new_line[xx]) * strength) / 100; -+ } -+ } -+ } -+ } -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap); -+ FT_Bitmap_Done(library, &new_bitmap); -+ } -+ -+ -+ /* Grayscale filter */ -+ static void -+ _ft_lcd_grayscale_filter ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_UInt strength, -+ FT_Library library ) -+ { -+ -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ FT_Byte* line = bitmap->buffer; -+ -+ for (height = (FT_UInt)bitmap->rows; height > 0; height--, line += bitmap->pitch ) -+ { -+ FT_UInt xx; -+ for ( xx = 0; xx < width - 1; xx += 3 ) -+ { -+ FT_UInt total = line [xx] + line [xx + 1] + line [xx + 2]; -+ line[xx] = ( (100-strength) * line[xx] + strength * (total / 3) ) / 100; -+ line[xx+1] = ( (100-strength) * line[xx+1] + strength * (total / 3) ) / 100; -+ line[xx+2] = ( (100-strength) * line[xx+2] + strength * (total / 3) ) / 100; -+ } -+ } -+ } -+ -+ -+ -+ /*************************************************************************/ -+ /* */ -+ /* */ -+ /* */ -+ /* */ -+ /* */ -+ /* */ -+ -+ -+ typedef struct SA_Rule_ -+ { -+ const char family[32]; -+ const int ppem[5]; -+ } SA_Rule; -+ -+#define STEM_WIDTH_2_PPEM 18 -+#define MAX_PPEM 100 -+ -+ -+ -+/* "Font name", {ppem where stem width becomes 1, -+ * ppem where stem width becomes 2... etc.} */ -+/* 100 means auto-calculate */ -+#define SNAPPING_STEM_WIDTHS_RULES_SIZE 21 -+ SA_Rule SNAPPING_STEM_WIDTHS_Rules -+ [SNAPPING_STEM_WIDTHS_RULES_SIZE] = -+ { -+ { "Andale Mono", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Arial Narrow", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Calibri", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Cantarell", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Century Gothic", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Comfortaa", {10, 19, 22, MAX_PPEM, MAX_PPEM} }, -+ { "Consolas", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Corbel", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Futura", {10, 14, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Gill Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Helvetica CY", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Inconsolata", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Liberation Sans Narrow", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Liberation Sans", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Lucida Grande", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Lucida Sans Unicode", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Luxi Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Open Sans", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Rokkitt", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Segoe UI", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} }, -+ { "Trebuchet MS", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} }, -+ }; -+ -+ -+/* "Font name", {ppem, scale_up=1|scale_down=0} */ -+#define SNAPPING_STEM_SCALING_RULES_SIZE 31 -+ SA_Rule SNAPPING_STEM_SCALING_Rules -+ [SNAPPING_STEM_SCALING_RULES_SIZE] = -+ { -+ { "Andale Mono", {11, 1,} }, -+ { "Bitstream Vera Sans", {12, 1,} }, -+ { "Calibri", {15, 1,} }, -+ { "Calibri", {17, 1,} }, -+ { "Calibri", {18, 1,} }, -+ { "Candara", {14, 1,} }, -+ { "Candara", {17, 1,} }, -+ { "Canwell", {13, 0,} }, -+ { "Comfortaa", {11, 0,} }, -+ { "Consolas", {11, 1,} }, -+ { "DejaVu Sans", {12, 1,} }, -+ { "Freesans", {16, 0,} }, -+ { "Freeserif", {13, 1,} }, -+ { "Freeserif", {17, 1,} }, -+ { "Inconsolata", {12, 1,} }, -+ { "Inconsolata", {15, 1,} }, -+ { "Lucida Grande", {13, 1,} }, -+ { "Myriad Pro", {14, 1,} }, -+ { "Myriad Pro", {17, 1,} }, -+ { "Nina", {11, 0,} }, -+ { "Nina", {12, 0,} }, -+ { "Nina", {13, 0,} }, -+ { "Optima", {17, 1,} }, -+ { "Raleway", {15, 0,} }, -+ { "Samba", {11, 0,} }, -+ { "Times New Roman", {17, 1,} }, -+ { "Trebuchet MS", {17, 0,} }, -+ { "Trebuchet MS", {13, 0,} }, -+ { "Trebuchet MS", {20, 1,} }, -+ { "Verdana", {12, 1,} }, -+ { "Verdana", {15, 1,} }, -+ }; -+ -+ -+/* "Font name", {ppem, scale_up=1|scale_down=0} */ -+#define SNAPPING_M_RULES_SIZE 9 -+ SA_Rule SNAPPING_M_Rules -+ [SNAPPING_M_RULES_SIZE] = -+ { -+ { "Courier New", {13, 1,} }, -+ { "Courier New", {14, 1,} }, -+ { "Courier", {13, 1,} }, -+ { "Courier", {14, 1,} }, -+ { "Droid Sans Mono", {12, 0,} }, -+ { "Bitstream Vera Sans", {12, 0,} }, -+ { "DejaVu Sans", {12, 0,} }, -+ { "Essential PragmataPro", {13, 0,} }, -+ { "Essential PragmataPro", {14, 0,} }, -+ }; -+ -+ -+/* "Font name", {ppem, ppem} */ -+#define SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE 1 -+ SA_Rule SNAPPING_SYNTHESIZE_STEMS_Rules -+ [SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE] = -+ { -+ { "---", {13, 13,} }, -+ }; -+ -+ -+/* "Font name", {ppem, ppem} */ -+#define SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE 1 -+ SA_Rule SNAPPING_NO_BEARING_CORRECTION_Rules -+ [SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE] = -+ { -+ { "Times New Roman", {0, 100,} }, -+ }; -+ -+ -+/* "Font name", {ppem, ppem} */ -+#define SNAPPING_EDGE_DETECTION_RULES_SIZE 8 -+ SA_Rule SNAPPING_EDGE_DETECTION_Rules -+ [SNAPPING_EDGE_DETECTION_RULES_SIZE] = -+ { -+ { "Tahoma", {11, 11,} }, -+ { "Courier New", {10, 12,} }, -+ { "Arial", {11, 11,} }, -+ { "Arial", {13, 13,} }, -+ { "Liberation Sans", {11, 11,} }, -+ { "FreeSans", {11, 11,} }, -+ { "FreeSans", {13, 13,} }, -+ { "Palatino Linotype", {0, 100,} }, -+ }; -+ -+/* "Font name", {ppem, translate_value} */ -+#define SNAPPING_STEM_TRANSLATING_RULES_SIZE 6 -+ SA_Rule SNAPPING_STEM_TRANSLATING_Rules -+ [SNAPPING_STEM_TRANSLATING_RULES_SIZE] = -+ { -+ { "Arial", {11, 32,} }, -+ { "Arial Unicode MS", {11, 32,} }, -+ { "FreeSans", {11, 32,} }, -+ { "Arimo", {11, 32,} }, -+ { "Liberation Sans", {11, 32,} }, -+ { "Tahoma", {11, 32,} }, -+ }; -+ -+/* "Font name", {ppem, translate_value} */ -+#define SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE 74 -+ SA_Rule SNAPPING_STEM_TRANSLATING_ONLY_Rules -+ [SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE] = -+ { -+ { "Arial Unicode MS", {10, 16,} }, -+ { "Arial Unicode MS", {8, 32,} }, -+ { "Arial Unicode MS", {9, 32,} }, -+ { "Arial", {10, 16,} }, -+ { "Arial", {8, 32,} }, -+ { "Arial", {9, 32,} }, -+ { "Arial", {16, -24,} }, -+ { "Arimo", {10, 8,} }, -+ { "Arimo", {8, 32,} }, -+ { "Arimo", {9, 32,} }, -+ { "Bitstream Vera Sans", {8, 16,} }, -+ { "Calibri", {10, 16,} }, -+ { "Calibri", {15, 0,} }, -+ { "Candara", {10, 16,} }, -+ { "Cantarell", {11, 0} }, -+ { "Cantarell", {12, 0} }, -+ { "Consolas", {8, 32,} }, -+ { "Consolas", {9, 32,} }, -+ { "Corbel", {10, 16,} }, -+ { "Courier", {13, 16,} }, -+ { "Courier", {15, 0,} }, -+ { "Dejavu Sans Mono", {7, 16,} }, -+ { "Dejavu Sans Mono", {8, 32,} }, -+ { "Dejavu Sans Mono", {9, 16,} }, -+ { "Dejavu Sans", {8, 16,} }, -+ { "Dejavu Sans", {15, -20,} }, -+ { "Droid Sans", {8, 16,} }, -+ { "Droid Sans", {9, 16,} }, -+ { "Freesans", {10, 16,} }, -+ { "Freesans", {9, 8,} }, -+ { "Georgia", {13, 16,} }, -+ { "Georgia", {14, 16,} }, -+ { "Georgia", {15, 0,} }, -+ { "Inconsolata", {10, 24,} }, -+ { "Inconsolata", {9, 32,} }, -+ { "Liberation Sans", {10, 8,} }, -+ { "Liberation Sans", {8, 32,} }, -+ { "Liberation Sans", {9, 32,} }, -+ { "Lucida Grande", {13, 24,} }, -+ { "Lucida Grande", {14, 24,} }, -+ { "Lucida Grande", {8, 16,} }, -+ { "Lucida Grande", {9, 16,} }, -+ { "Lucida Sans Unicode", {13, 24,} }, -+ { "Lucida Sans Unicode", {14, 24,} }, -+ { "Lucida Sans Unicode", {8, 16,} }, -+ { "Lucida Sans Unicode", {9, 16,} }, -+ { "Microsoft Sans Serif", {10, 16,} }, -+ { "Microsoft Sans Serif", {8, 32,} }, -+ { "Microsoft Sans Serif", {9, 32,} }, -+ { "Myriad Pro", {10, 16,} }, -+ { "Myriad Pro", {11, 0,} }, -+ { "Myriad Pro", {9, 16,} }, -+ { "Open Sans", {10, 16,} }, -+ { "Open Sans", {9, 16,} }, -+ { "Optima", {10, 0} }, -+ { "Optima", {11, 0} }, -+ { "Optima", {12, 0} }, -+ { "Segoe UI", {10, 0,} }, -+ { "Segoe UI", {7, 32,} }, -+ { "Segoe UI", {8, 16,} }, -+ { "Segoe UI", {9, 24,} }, -+ { "Tahoma", {7, 32,} }, -+ { "Tahoma", {8, 32,} }, -+ { "Tahoma", {9, 32,} }, -+ { "Times New Roman", {17, 8,} }, -+ { "Trebuchet MS", {10, 16,} }, -+ { "Trebuchet MS", {11, 0,} }, -+ { "Trebuchet MS", {8, 32,} }, -+ { "Trebuchet MS", {9, 32,} }, -+ { "Verdana", {8, 16,} }, -+ { "Verdana", {15, 16,} }, -+ { "Verdana", {14, 32,} }, -+ { "Verdana", {18, 32,} }, -+ { "Verdana", {19, 24,} }, -+ }; -+ -+ -+/* "Font name", {start ppem, end ppem} */ -+#define ALWAYS_USE_100_RULES_SIZE 46 -+ SA_Rule ALWAYS_USE_100_Rules -+ [ALWAYS_USE_100_RULES_SIZE] = -+ { -+ { "Andale Mono", {0, MAX_PPEM,} }, -+ { "Arial Unicode MS", {0, MAX_PPEM,} }, -+ { "Arial", {0, MAX_PPEM,} }, -+ { "Arimo", {0, MAX_PPEM,} }, -+ { "Bitstream Vera Sans Mono", {0, MAX_PPEM,} }, -+ { "Bitstream Vera Sans", {10, 14,} }, -+ { "Bitstream Vera Sans", {16, 17,} }, -+ { "Calibri", {23, MAX_PPEM,} }, -+ { "Consolas", {0, MAX_PPEM,} }, -+ { "Courier New", {12, 12,} }, -+ { "Courier", {0, MAX_PPEM,} }, -+ { "Cousine", {0, MAX_PPEM,} }, -+ { "DejaVu Sans Mono", {0, MAX_PPEM,} }, -+ { "DejaVu Sans", {10, 14,} }, -+ { "DejaVu Sans", {16, 17,} }, -+ { "Droid Sans", {12, 12,} }, -+ { "Droid Sans", {15, 15,} }, -+ { "FreeMono", {0, MAX_PPEM,} }, -+ { "FreeSans", {0, MAX_PPEM,} }, -+ { "Liberation Mono", {0, MAX_PPEM,} }, -+ { "Lucida Console", {0, MAX_PPEM,} }, -+ { "Luxi Sans", {13, 13,} }, -+ { "Microsoft Sans Serif", {0, MAX_PPEM,} }, -+ { "Monaco", {0, MAX_PPEM,} }, -+ { "Segoe UI", {11, 12,} }, -+ { "Segoe UI", {14, 14,} }, -+ { "Tahoma", {11, 11,} }, -+ { "Tahoma", {14, MAX_PPEM,} }, -+ { "Times New Roman", {14, 14,} }, -+ { "Times New Roman", {16, 16,} }, -+ { "Trebuchet MS", {13, 13,} }, -+ { "Ubuntu", {12, 13,} }, -+ { "Ubuntu", {15, 15,} }, -+ { "Verdana", {0, 14,} }, -+ { "Verdana", {16, MAX_PPEM,} }, -+ { "Pragmata", {0, MAX_PPEM,} }, -+ { "Essential PragmataPro", {0, MAX_PPEM,} }, -+ }; -+ -+ -+ -+ -+#define AUTOHINT_BRIGHTNESS_RULES_SIZE 3 -+ SA_Rule BRIGHTNESS_Rules -+ [AUTOHINT_BRIGHTNESS_RULES_SIZE] = -+ { -+ { "Baskerville", {0, -20,} }, -+ { "Garamond", {0, -20,} }, -+ { "Optima", {0, -20,} }, -+ }; -+ -+#define AUTOHINT_CONTRAST_RULES_SIZE 3 -+ SA_Rule CONTRAST_Rules -+ [AUTOHINT_CONTRAST_RULES_SIZE] = -+ { -+ { "Baskerville", {0, 25,} }, -+ { "Garamond", {0, 25,} }, -+ { "Optima", {0, 25,} }, -+ }; -+ -+#if 0 -+#define STEM_SPACING_RULES_SIZE 3 -+ SA_Rule STEM_SPACING_Rules -+ [STEM_SPACING_RULES_SIZE] = -+ { -+ { "Tahoma", {10, 12, 18, 18, 30} }, -+ { "Arial", {10, 11, 23, 25, 30} }, -+ { "Freesans", {10, 12, 18, 18, 30} }, -+ }; -+ -+#define STEM_START_RULES_SIZE 3 -+ SA_Rule STEM_START_Rules -+ [STEM_START_RULES_SIZE] = -+ { -+ { "Tahoma", {14, 17, 30, 100, 100} }, -+ { "Arial", {11, 18, 23, 30, 30} }, -+ { "Freesans", {10, 18, 18, 25, 30} }, -+ }; -+#endif -+ -+ typedef struct Stem_Data_ -+ { -+ FT_Int stem_width; -+ FT_Int stem_spacing; -+ FT_Int stem_start; -+ FT_Int stem_scaling; -+ FT_Int stem_translating_only; -+ FT_Int stem_translating; -+ FT_Int brightness; -+ FT_Int contrast; -+ FT_Bool use_100; -+ FT_Bool synth_stems; -+ FT_Bool edge_detection; -+ FT_Bool bearing_correction; -+ FT_Int m; -+ } Stem_Data; -+ -+ -+ typedef struct Stem_Segment_ -+ { -+ FT_Long x1; -+ FT_Long x2; -+ FT_Int y; -+ } Stem_Segment; -+ -+ typedef struct Stem_Center_ -+ { -+ FT_Long x; -+ FT_Long y; -+ FT_Long w; -+ FT_Long x1; -+ FT_Long x2; -+ } Stem_Center; -+ -+ typedef struct Stem_ -+ { -+ FT_Long center; -+ FT_Long count; -+ FT_Long rcount; /* used to count within a range in possible stems */ -+ FT_Long width; -+ FT_Long height; -+ FT_Short zone; /* 1 2 or 3 */ -+ FT_Bool generated; -+ } Stem; -+ -+ -+ static void -+ swap_stem ( Stem* s1, Stem* s2 ) -+ { -+ Stem s; -+ s.center = s1->center; -+ s.count = s1->count; -+ s.rcount = s1->rcount; -+ s.width = s1->width; -+ s.zone = s1->zone; -+ s.generated = s1->generated; -+ -+ s1->center = s2->center; -+ s1->count = s2->count; -+ s1->rcount = s2->rcount; -+ s1->width = s2->width; -+ s1->zone = s2->zone; -+ s1->generated = s2->generated; -+ -+ s2->center = s.center; -+ s2->count = s.count; -+ s2->rcount = s.rcount; -+ s2->width = s.width; -+ s2->zone = s.zone; -+ s2->generated = s.generated; -+ } -+ -+ -+ FT_LOCAL_DEF( void ) -+ sa_fill_known_stem_values ( -+ FT_String* family, -+ int ppem, -+ FT_String* style, -+ FT_UInt num_stems, -+ Stem_Data* known_stem_values ) -+ { -+ FT_Int i, j; -+ if (verbose) printf("%s ", family); -+ -+ i = 0; -+ while ( i < SNAPPING_STEM_WIDTHS_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_STEM_WIDTHS_Rules[i].family, family ) == 0 ) ) -+ { -+ j = 0; -+ known_stem_values->stem_width = 1; -+ -+ while (j < 4) -+ { -+ if (SNAPPING_STEM_WIDTHS_Rules[i].ppem[j] == MAX_PPEM ) -+ { -+ known_stem_values->stem_width = -1; /* use default */ -+ j = 5; -+ i = SNAPPING_STEM_WIDTHS_RULES_SIZE; -+ } -+ else if (ppem < SNAPPING_STEM_WIDTHS_Rules[i].ppem[j]) -+ { -+ known_stem_values->stem_width = j; -+ j = 5; -+ i = SNAPPING_STEM_WIDTHS_RULES_SIZE; -+ } -+ j++; -+ } -+ } -+ i++; -+ } -+ -+ i = 0; -+ while ( i < SNAPPING_STEM_SCALING_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_STEM_SCALING_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->stem_scaling = -1; /* default */ -+ -+ if (ppem == SNAPPING_STEM_SCALING_Rules[i].ppem[0]) -+ { -+ known_stem_values->stem_scaling = SNAPPING_STEM_SCALING_Rules[i].ppem[1]; -+ i = SNAPPING_STEM_SCALING_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+ i = 0; -+ while ( i < SNAPPING_M_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_M_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->m = -1; /* default */ -+ -+ if (ppem == SNAPPING_M_Rules[i].ppem[0]) -+ { -+ known_stem_values->m = SNAPPING_M_Rules[i].ppem[1]; -+ i = SNAPPING_M_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ i = 0; -+ while ( i < SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->stem_translating_only = -1024; /* default */ -+ -+ if (ppem == SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0] -+ || SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0] == 0) -+ { -+ known_stem_values->stem_translating_only = SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[1]; -+ i = SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ i = 0; -+ while ( i < SNAPPING_STEM_TRANSLATING_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_STEM_TRANSLATING_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->stem_translating = 0; /* default */ -+ -+ if (ppem == SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0] -+ || SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0] == 0) -+ { -+ known_stem_values->stem_translating = SNAPPING_STEM_TRANSLATING_Rules[i].ppem[1]; -+ i = SNAPPING_STEM_TRANSLATING_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+ i = 0; -+ while ( i < ALWAYS_USE_100_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( ALWAYS_USE_100_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->use_100 = FALSE; /* default */ -+ -+ if (ppem >= ALWAYS_USE_100_Rules[i].ppem[0] && ppem <= ALWAYS_USE_100_Rules[i].ppem[1] ) -+ { -+ known_stem_values->use_100 = TRUE; -+ i = ALWAYS_USE_100_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+ i = 0; -+ while ( i < SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_SYNTHESIZE_STEMS_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->synth_stems = FALSE; /* default */ -+ -+ if (ppem >= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[0] && ppem <= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[1] ) -+ { -+ known_stem_values->synth_stems = TRUE; -+ i = SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+ i = 0; -+ while ( i < SNAPPING_EDGE_DETECTION_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_EDGE_DETECTION_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->edge_detection = FALSE; /* default */ -+ -+ if (ppem >= SNAPPING_EDGE_DETECTION_Rules[i].ppem[0] && ppem <= SNAPPING_EDGE_DETECTION_Rules[i].ppem[1] ) -+ { -+ known_stem_values->edge_detection = TRUE; -+ i = SNAPPING_EDGE_DETECTION_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+ i = 0; -+ while ( i < SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( SNAPPING_NO_BEARING_CORRECTION_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->bearing_correction = TRUE; /* default */ -+ -+ if (ppem >= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[0] && ppem <= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[1] ) -+ { -+ known_stem_values->bearing_correction = FALSE; -+ i = SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ -+#if 0 -+ i = 0; -+ while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->brightness = 0.0; -+ -+ if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0) -+ { -+ known_stem_values->brightness = BRIGHTNESS_Rules[i].ppem[1]; -+ i = AUTOHINT_BRIGHTNESS_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ i = 0; -+ while ( i < AUTOHINT_CONTRAST_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) ) -+ { -+ known_stem_values->contrast = 0.0; -+ -+ if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0) -+ { -+ known_stem_values->contrast = CONTRAST_Rules[i].ppem[1]; -+ i = AUTOHINT_CONTRAST_RULES_SIZE; -+ } -+ } -+ i++; -+ } -+ -+ for ( i = 0; i <= STEM_SPACING_RULES_SIZE; i++ ) -+ { -+ if ( family && -+ ( strcasecmp( STEM_SPACING_Rules[i].family, family ) == 0 ) ) -+ { -+ j = 0; -+ known_stem_values->stem_spacing = 2; /* default */ -+ -+ while (j < 4) -+ { -+ if (ppem < STEM_SPACING_Rules[i].ppem[j]) -+ { -+ known_stem_values->stem_spacing = j; -+ j = 5; -+ } -+ j++; -+ } -+ } -+ } -+ -+ -+ for ( i = 0; i <= STEM_START_RULES_SIZE; i++ ) -+ { -+ if ( family && -+ ( strcasecmp( STEM_START_Rules[i].family, family ) == 0 ) ) -+ { -+ j = 0; -+ known_stem_values->stem_start = 1; /* default */ -+ -+ while (j < 4) -+ { -+ if (ppem < STEM_START_Rules[i].ppem[j]) -+ { -+ known_stem_values->stem_start = j; -+ j = 5; -+ } -+ j++; -+ } -+ } -+ } -+#endif -+ } -+ -+ -+ FT_LOCAL_DEF( FT_Int ) -+ get_contrast ( -+ FT_String* family, -+ int ppem) -+ { -+ FT_Int i; -+ if (verbose) printf("%s ", family); -+ -+ i = 0; -+ while ( i < AUTOHINT_CONTRAST_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) ) -+ { -+ if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0) -+ { -+ return CONTRAST_Rules[i].ppem[1]; -+ } -+ } -+ i++; -+ } -+ return 0; -+ } -+ -+ -+ FT_LOCAL_DEF( FT_Int ) -+ get_brightness ( -+ FT_String* family, -+ int ppem) -+ { -+ FT_Int i; -+ if (verbose) printf("%s ", family); -+ -+ i = 0; -+ while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE ) -+ { -+ if ( family && -+ ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) ) -+ { -+ if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0) -+ { -+ return BRIGHTNESS_Rules[i].ppem[1]; -+ } -+ } -+ i++; -+ } -+ return 0; -+ } -+ -+ -+ /* Stem alignment for bitmaps; A hack with very nice results */ -+ /* Ideally this could be implemented on the outline, prior to -+ * rasterization. Possible future enhancement is to use the -+ * warper code to achieve this */ -+ static void -+ _lcd_stem_align ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_GlyphSlot slot, -+ FT_Long* translate_value, -+ float* scale_value, -+ FT_UInt alignment_strength, -+ FT_UInt fitting_strength, -+ float* embolden_value -+ ) -+ { -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ -+ Stem_Segment* segments; -+ Stem_Segment* leftmost_segment; -+ Stem_Segment* rightmost_segment; -+ Stem_Segment* leftmost_segment_not_extrema; -+ Stem_Segment* rightmost_segment_not_extrema; -+ Stem* stems; -+ Stem* possible_stems; -+ Stem* leftmost_stem; -+ Stem* rightmost_stem; -+ Stem_Data* known_stem_values; -+ Stem_Center* centers; -+ FT_Long leftmost_point = width * 256; -+ FT_Long rightmost_point = 0; -+ FT_Long leftmost_point_not_extrema = width * 256; -+ FT_Long rightmost_point_not_extrema = 0; -+ FT_Long num_segments = 0; -+ FT_Long num_centers = 0; -+ FT_Long stem_centers[width * 256]; -+ FT_UInt h; -+ FT_ULong valid_stems = 0, valid_possible_stems = 0; -+ FT_Long center, stem_matches, stem_matches_ledge; -+ FT_Long stem_matches_redge, next_center, last_matching_center; -+ FT_Long last_matching_ledge, last_matching_redge, this_center; -+ FT_Int max_strength; -+ FT_Byte* line = bitmap->buffer; -+ FT_UInt current_value = 0; -+ FT_UInt xx; -+ FT_Long linearHoriAdvance = slot->linearHoriAdvance >> 10; -+ -+ FT_Int m_horiBearingX = slot->metrics.horiBearingX; -+ FT_Int m_horiAdvance = slot->metrics.horiAdvance; -+ FT_Int m_width = slot->metrics.width; -+ FT_Pos one_pixel = 768; -+ FT_Pos one_third_pixel = 256; -+ FT_Int columns_per_pixel = 3; -+ /*FT_Int extra_columns = 6;*/ -+ -+ /* on / off flags for testing different features */ -+ FT_Bool strategy_translate_using_closest_stem = TRUE; -+ FT_Bool strategy_scale_to_closest_centers = FALSE; -+ FT_Bool strategy_scale_to_closest_centers_up_only = FALSE; -+ FT_Bool strategy_always_use_distance_ceiling = FALSE; -+ FT_Bool strategy_auto_change_center_offset = TRUE; -+ FT_Bool strategy_use_m_control = FALSE; -+ FT_Bool strategy_correct_out_of_bounds_outlines = FALSE; /*this needs work.. breaks some glyphs like verdana 12 */ -+ FT_Bool strategy_also_use_edge_detection_for_stems = FALSE; -+ FT_Bool strategy_use_strengths = TRUE; -+ FT_Bool strategy_synthesize_stems = FALSE; -+ FT_Bool strategy_bearing_correction = TRUE; -+ FT_Bool strategy_use_d_correction = TRUE; -+ FT_Bool strategy_fit_to_width = FALSE; -+ /*FT_Bool strategy_center_glyph = FALSE;*/ -+ FT_Bool strategy_use_verdana_12_hack = FALSE; /* not necessary anymore... maybe */ -+ FT_Bool has_serifs = FALSE; -+ FT_Bool autohinted = FALSE; -+ -+ const FT_Int MIN_PPEM = 7; -+ /*const FT_Int MAX_PPEM = 100;*/ -+ const FT_Int MAX_STEMS = 3; -+ FT_Int ppem = 0; -+ -+ int checked_use_known_settings_on_selected_fonts_env = 0; -+ FT_Bool use_known_settings_on_selected_fonts = FALSE; -+ -+ int cur_width; -+ char *cur_width_env = getenv( "CUR_WIDTH" ); -+ -+ if ( cur_width_env != NULL ){ -+ sscanf ( cur_width_env, "%d", &cur_width ); -+ if (cur_width != 0) autohinted = TRUE; -+ } -+ -+ /* An incoming scale value of 1.1 indicates to do certain things */ -+ /*if (*scale_value == 1.1) strategy_use_verdana_12_hack = TRUE;*/ -+ -+ /* reset to default */ -+ *scale_value = 1.0; -+ -+ if ( checked_use_known_settings_on_selected_fonts_env == 0 ) -+ { -+ char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" ); -+ if ( use_known_settings_on_selected_fonts_env != NULL ) -+ { -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ } -+ } -+ checked_use_known_settings_on_selected_fonts_env = 1; -+ } -+ -+ -+ /* Simply return in odd cases where these don't seem to be set */ -+ /* Flash and some pdf viewers will crash otherwise */ -+ if ( !slot->face || !slot->face->size || !slot->face->size->metrics.x_ppem ) -+ return; -+ if ( slot->face->size->metrics.x_ppem > MAX_PPEM ) return; -+ /*if ( width < 4 ) return;*/ -+ -+ if ( slot->face->size->metrics.x_ppem < MIN_PPEM ) return; -+ -+ if ( !FT_IS_SCALABLE( slot->face ) ) return; -+ -+ ppem = slot->face->size->metrics.x_ppem; -+ -+ -+ /* only perform alignment on styles we know, that aren't bold or italic */ -+ /* perhaps detection could be added on those that are not set? */ -+ /* Require certain ppems for narrow and light fonts */ -+ if( slot->face->style_name ) -+ { -+ if ( strcasestr(slot->face->style_name, "Italic") -+ || strcasestr(slot->face->style_name, "Oblique") -+ || strcasestr(slot->face->style_name, "Script") -+ || strcasestr(slot->face->style_name, "Handwriting") -+ || strcasestr(slot->face->style_name, "Bold") -+ || strcasestr(slot->face->style_name, "Black") -+ || ( ( strcasestr(slot->face->style_name, "Extra Thin") -+ || strcasestr(slot->face->style_name, "Extra Light") ) -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->style_name, "Thin") -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->style_name, "Light") -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->style_name, "Narrow") -+ && ppem < 15 ) -+ || ( strcasestr(slot->face->style_name, "Condensed") -+ && ppem < 20 ) ) -+ return; -+ } -+ -+ if( slot->face->family_name ) -+ { -+ if ( strcasestr(slot->face->family_name, "Italic") -+ || strcasestr(slot->face->family_name, "Oblique") -+ || strcasestr(slot->face->family_name, "Script") -+ || strcasestr(slot->face->family_name, "Handwriting") -+ || strcasestr(slot->face->family_name, "Bold") -+ || strcasestr(slot->face->family_name, "Black") -+ || ( ( strcasestr(slot->face->family_name, "Extra Thin") -+ || strcasestr(slot->face->family_name, "Extra Light") ) -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->family_name, "Thin") -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->family_name, "Light") -+ && ppem < 10 ) -+ || ( strcasestr(slot->face->family_name, "Narrow") -+ && ppem < 15 ) -+ || ( strcasestr(slot->face->family_name, "Condensed") -+ && ppem < 20 ) ) -+ return; -+ } -+ else if ( slot->face->style_flags ) -+ { -+ if ( slot->face->style_flags & FT_STYLE_FLAG_ITALIC -+ || slot->face->style_flags & FT_STYLE_FLAG_BOLD -+ || FT_IS_TRICKY( slot->face ) ) -+ return; -+ } -+ else return; -+ -+ if( slot->face->family_name ) -+ { -+ if ( strcasestr(slot->face->family_name, "Courier") -+ || strcasestr(slot->face->family_name, "Serif") -+ || strcasestr(slot->face->family_name, "Times")) -+ has_serifs = TRUE; -+ } -+ -+ if ( mode != FT_RENDER_MODE_LCD ) -+ { -+ columns_per_pixel = 1; -+ one_pixel = 256; -+ one_third_pixel = 85; -+ /*extra_columns = 0;*/ -+ /* until this can be figured out just return */ -+ /* There are issues with missing glyphs */ -+ return; -+ } -+ -+ known_stem_values = (Stem_Data*) malloc (columns_per_pixel * sizeof(Stem_Data)); /* only look at top 3 for now */ -+ known_stem_values->stem_spacing = -1; -+ known_stem_values->stem_width = -1; -+ known_stem_values->stem_start = -1; -+ known_stem_values->stem_scaling = -1; -+ known_stem_values->stem_translating_only = -1024; -+ known_stem_values->stem_translating = 0; -+ known_stem_values->brightness = 0; -+ known_stem_values->contrast = 0; -+ known_stem_values->use_100 = FALSE; -+ known_stem_values->m = -1; -+ known_stem_values->synth_stems = FALSE; -+ known_stem_values->bearing_correction = TRUE; -+ -+ if (use_known_settings_on_selected_fonts) -+ { -+ sa_fill_known_stem_values ( slot->face->family_name, -+ ppem, slot->face->style_name, -+ valid_stems, known_stem_values ); -+ if (verbose) -+ printf ("width:%d,spacing:%d,start:%d,scaling:%d,translate:%d ", -+ known_stem_values->stem_width, known_stem_values->stem_spacing, -+ known_stem_values->stem_start, known_stem_values->stem_scaling, -+ known_stem_values->stem_translating_only) ; -+ } -+ -+ /* translate value may be set for < 10 */ -+ if (use_known_settings_on_selected_fonts && known_stem_values->stem_translating_only > -1024 ) -+ { -+ *translate_value = known_stem_values->stem_translating_only; -+ return; -+ } -+ -+ if (use_known_settings_on_selected_fonts && known_stem_values->bearing_correction == FALSE ) -+ { -+ strategy_bearing_correction = FALSE; -+ } -+ -+ if ( known_stem_values->use_100 || known_stem_values->m >= 0) -+ { -+ alignment_strength = fitting_strength = 100; -+ strategy_use_m_control = TRUE; -+ } -+ -+ if ( known_stem_values->edge_detection ) -+ { -+ strategy_also_use_edge_detection_for_stems = TRUE; -+ } -+ -+ if ( ppem < 9 ) return; -+ if ( ppem > 20 ) strategy_use_m_control = TRUE; -+ -+ /* Allocate */ -+ segments = (Stem_Segment*) malloc( (1) * sizeof (Stem_Segment)); -+ leftmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment)); -+ leftmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment)); -+ rightmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment)); -+ rightmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment)); -+ -+ stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem)); -+ possible_stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem)); -+ leftmost_stem = (Stem*) malloc ( sizeof(Stem)); -+ rightmost_stem = (Stem*) malloc ( sizeof(Stem)); -+ centers = (Stem_Center*) malloc ( (1) * sizeof(Stem_Center)); -+ -+ if (verbose) printf("\n"); -+ -+ /* Initialize */ -+ for ( xx = 0; xx < width * 256; xx += 1 ) -+ { -+ stem_centers[xx] = 0; -+ } -+ for ( xx = 0; xx < num_segments; xx += 1 ) -+ { -+ segments[xx].x1 = 0; -+ segments[xx].x2 = 0; -+ segments[xx].y = 0; -+ } -+ rightmost_segment->x1 = 0; -+ rightmost_segment->x2 = 0; -+ rightmost_segment->y = 0; -+ leftmost_segment->x1 = 99999999; -+ leftmost_segment->x2 = 0; -+ leftmost_segment->y = 0; -+ -+ rightmost_segment_not_extrema->x1 = 0; -+ rightmost_segment_not_extrema->x2 = 0; -+ rightmost_segment_not_extrema->y = 0; -+ leftmost_segment_not_extrema->x1 = 99999999; -+ leftmost_segment_not_extrema->x2 = 0; -+ leftmost_segment_not_extrema->y = 0; -+ -+ /* Locate stem centers for later processing */ -+ for ( h = (FT_UInt)bitmap->rows; h > 0; h--, line += bitmap->pitch ) -+ { -+ current_value = 0; -+ /* Calculate various sums and stem widths of glyph */ -+ for ( xx = 0; xx < width; xx += 1 ) -+ { -+ /* Reallocate */ -+ segments = (Stem_Segment*) realloc( segments, (num_segments + 1) * sizeof (Stem_Segment)); -+ -+ /* if line is white, and now has color, it's the start of a stem */ -+ if (current_value == 0 && line[xx] > 0) -+ { -+ /* start of stem */ -+ segments[num_segments].x1 = 256 * (xx) + (255 - line[xx]); -+ segments[num_segments].y = h; -+ } -+ -+ /* otherwise, if it's currently black and the new value is 0, it's the end of a stem */ -+ else if ( ( current_value > 0 && line[xx] == 0 ) -+ || ( current_value > 0 && xx == width - 1 ) ) -+ { -+ FT_Long stem_center_x/*, stem_width*/; -+ segments[num_segments].x2 = 256 * (xx-1) + line[xx-1]; -+ -+ if (xx == width - 1) segments[num_segments].x2 += line[xx]; -+ -+ /*stem center is average of start and end of stem */ -+ stem_center_x = (segments[num_segments].x2 + segments[num_segments].x1) / 2; -+ /*stem_width = segments[num_segments].x2 - segments[num_segments].x1;*/ -+ /* Reallocate */ -+ centers = (Stem_Center*) realloc ( centers, (num_centers + 1) * sizeof(Stem_Center)); -+ centers[num_centers].x = stem_center_x; -+ centers[num_centers].y = h; -+ centers[num_centers].x1 = segments[num_segments].x1; -+ centers[num_centers].x2 = segments[num_segments].x2; -+ -+ num_centers++; -+ -+ stem_centers[stem_center_x] += 1; -+ -+ /* Find left and rightmost points for later calculations */ -+ /* OR - Favor ones that aren't on the top or bottom if possible to prevent v and w from getting caught later */ -+ if ( segments[num_segments].x1 < leftmost_segment->x1 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height -+ && segments[num_segments].x1 == leftmost_segment->x1 ) ) -+ { -+ leftmost_segment->x1 = segments[num_segments].x1; -+ leftmost_segment->x2 = segments[num_segments].x2; -+ leftmost_segment->y = h; -+ } -+ if (segments[num_segments].x2 > rightmost_segment->x2 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height -+ && segments[num_segments].x1 == rightmost_segment->x1 ) ) -+ { -+ rightmost_segment->x1 = segments[num_segments].x1; -+ rightmost_segment->x2 = segments[num_segments].x2; -+ rightmost_segment->y = h; -+ } -+ -+ if (segments[num_segments].x1 < leftmost_segment_not_extrema->x1 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height -+ && segments[num_segments].x1 == leftmost_segment_not_extrema->x1 -+ && h < (FT_UInt)bitmap->rows && h > 0 ) ) -+ { -+ leftmost_segment_not_extrema->x1 = segments[num_segments].x1; -+ leftmost_segment_not_extrema->x2 = segments[num_segments].x2; -+ leftmost_segment_not_extrema->y = h; -+ } -+ if (segments[num_segments].x2 > rightmost_segment_not_extrema->x2 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height -+ && segments[num_segments].x1 == rightmost_segment_not_extrema->x1 -+ && h < (FT_UInt)bitmap->rows && h > 0 ) ) -+ { -+ rightmost_segment_not_extrema->x1 = segments[num_segments].x1; -+ rightmost_segment_not_extrema->x2 = segments[num_segments].x2; -+ rightmost_segment_not_extrema->y = h; -+ } -+ -+ if (segments[num_segments].x1 < leftmost_point) -+ { -+ leftmost_point = segments[num_segments].x1; -+ } -+ if (segments[num_segments].x2 > rightmost_point) -+ { -+ rightmost_point = segments[num_segments].x2; -+ } -+ -+ if (segments[num_segments].x1 < leftmost_point_not_extrema -+ && h < (FT_UInt)bitmap->rows && h > 0) -+ { -+ leftmost_point_not_extrema = segments[num_segments].x1; -+ } -+ if (segments[num_segments].x2 > rightmost_point_not_extrema -+ && h < (FT_UInt)bitmap->rows && h > 0) -+ { -+ rightmost_point_not_extrema = segments[num_segments].x2; -+ } -+ -+ num_segments++; -+ } -+ /* else - other conditions - need some error checking here */ -+ -+ current_value = line[xx]; -+ } -+ } -+ -+ /* initialize */ -+ for ( xx = 0; xx < MAX_STEMS; xx +=1 ) -+ { -+ stems[xx].center = 0; -+ stems[xx].count = 0; -+ stems[xx].width = 0; -+ stems[xx].height = 0; -+ possible_stems[xx].center = 0; -+ possible_stems[xx].count = 0; -+ possible_stems[xx].width = 0; -+ possible_stems[xx].height = 0; -+ } -+ valid_stems = 0; -+ valid_possible_stems = 0; -+ -+ /* Determine which centers belong to stems */ -+ center = 0; -+ -+ while ( center < num_centers ) -+ { -+ /* slope at within which to consider a point part of a stem */ -+ /*const FT_UInt slope = 1; -+ const FT_UInt topslope = (256 * 3) / 10; */ -+ FT_Int deviation1 = 5; /* 10 to 20 wiith 4 matches seems good, but 1 or 2 with 3 stems needs to somehow get included */ -+ FT_Int deviation2=-1, requirement1 = 4, stem_match_requirement = 3; -+ FT_Int best_height = 0, center_difference_in_height; -+ FT_Int center_difference_in_width, valid_center_average; -+ FT_Int smallest_width_ledge, smallest_width_redge; -+ FT_Int x1_difference_in_width, x2_difference_in_width; -+ FT_Bool large_gap_found = FALSE, no_gap_found = FALSE; -+ FT_Bool large_gap_found_ledge = FALSE, no_gap_found_ledge = FALSE; -+ FT_Bool large_gap_found_redge = FALSE, no_gap_found_redge = FALSE; -+ FT_Bool stem_detected = FALSE; -+ FT_Int set_width_to, set_center_to; -+ -+ /* seems to not do damage */ -+ /* May not be effective */ -+ requirement1 = height / 4; -+ if (requirement1 < 5) requirement1 = 5; -+ deviation1 = 20; -+ deviation2 = 20; -+ -+ if (columns_per_pixel == 1) -+ { -+ deviation1 = deviation2 = 10; -+ } -+ -+ if ((FT_Int)bitmap->rows <= 6) deviation1 = 25; -+ if ((FT_Int)bitmap->rows <= 6) deviation2 = 25; -+ -+ if (columns_per_pixel == 1 && (FT_Int)bitmap->rows <= 6) -+ { -+ deviation1 = deviation2 = 12; -+ } -+ -+ /* THIS WORKS, BUT NEED TO PUNISH DIAGONALS like W */ -+ /*requirement2 = height / 5; -+ if (requirement2 < 3) requirement2 = 3; -+ deviation2 = 1 ;*/ -+ valid_center_average = 0; -+ /* if (deviation2 < 1) deviation2 = 1;*/ -+ -+ large_gap_found = large_gap_found_ledge = large_gap_found_redge = FALSE; -+ no_gap_found = no_gap_found_ledge = no_gap_found_redge = FALSE; -+ stem_detected = FALSE; -+ -+ if (ppem < 11) -+ { -+ requirement1 = 4; -+ } -+ if (ppem > 18 ) -+ { -+ stem_match_requirement = height / 4; -+ if (stem_match_requirement < 3) stem_match_requirement = 3; -+ } -+ -+ smallest_width_ledge = smallest_width_redge = width * 256; -+ stem_matches = 0; -+ stem_matches_ledge = 0; -+ stem_matches_redge = 0; -+ last_matching_center = -1; -+ last_matching_ledge = -1; -+ last_matching_redge = -1; -+ -+ /* set currently looked at center to center value */ -+ this_center = center; -+ next_center = 0; -+ -+ /* For each center, compare with all other centers to see if others match the properties of this one */ -+ while ( next_center < num_centers ) -+ { -+ -+ /* calculate differences */ -+ center_difference_in_width = abs (centers[this_center].x - centers[next_center].x); -+ center_difference_in_height = abs (centers[this_center].y - centers[next_center].y); -+ x1_difference_in_width = abs (centers[this_center].x1 - centers[next_center].x1); -+ x2_difference_in_width = abs (centers[this_center].x2 - centers[next_center].x2); -+ -+ -+ /* property - stem center points that align */ -+ /* if the center is within range, the center is less than 1/2 the height away, and at least one edge is also within range */ -+ if ( center_difference_in_width < center_difference_in_height * deviation1 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2 -+ /* prevents w from getting caught ---- but also kills m */ -+ && (x1_difference_in_width < center_difference_in_height * deviation2 -+ || x2_difference_in_width < center_difference_in_height * deviation2 ) -+ -+ ) -+ { -+ stem_matches += 1; -+ valid_center_average += centers[next_center].x; -+ /* try to find where the matching centers are far apart */ -+ if (last_matching_center >= 0 -+ && abs(centers[last_matching_center].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2) -+ large_gap_found = TRUE; -+ /* try to find where matching centers are next to each other */ -+ if (last_matching_center >= 0 -+ && abs(centers[last_matching_center].y - centers[next_center].y) == 1) -+ no_gap_found = TRUE; -+ last_matching_center = next_center; -+ } -+ -+ if (strategy_also_use_edge_detection_for_stems){ -+ /* property - stem left edge points that align */ -+ /* if the center is within range, the center is less than 1/2 the height away */ -+ if ( x1_difference_in_width < center_difference_in_height * deviation1 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2 ) -+ { -+ stem_matches_ledge += 1; -+ /* may not need for edges */ -+ /*valid_center_average += centers[next_center].x; */ -+ -+ if (centers[next_center].x2 - centers[next_center].x1 < smallest_width_ledge ) -+ smallest_width_ledge = centers[next_center].x2 - centers[next_center].x1; -+ -+ /* try to find where the matching centers are far apart */ -+ if (last_matching_ledge >= 0 -+ && abs(centers[last_matching_ledge].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2) -+ large_gap_found_ledge = TRUE; -+ /* try to find where matching centers are next to each other */ -+ if (last_matching_ledge >= 0 -+ && abs(centers[last_matching_ledge].y - centers[next_center].y) == 1) -+ no_gap_found_ledge = TRUE; -+ last_matching_ledge = next_center; -+ } -+ } -+ -+ if (strategy_also_use_edge_detection_for_stems){ -+ /* property - stem right edge points that align */ -+ /* if the center is within range, the center is less than 1/2 the height away */ -+ if ( x2_difference_in_width < center_difference_in_height * deviation1 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2 ) -+ { -+ stem_matches_redge += 1; -+ /* may not need for edges */ -+ /*valid_center_average += centers[next_center].x; */ -+ -+ if (centers[next_center].x2 - centers[next_center].x1 < smallest_width_redge ) -+ smallest_width_redge = centers[next_center].x2 - centers[next_center].x1; -+ -+ /* try to find where the matching centers are far apart */ -+ if (last_matching_redge >= 0 -+ && abs(centers[last_matching_redge].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2) -+ large_gap_found_redge = TRUE; -+ /* try to find where matching centers are next to each other */ -+ if (last_matching_redge >= 0 -+ && abs(centers[last_matching_redge].y - centers[next_center].y) == 1) -+ no_gap_found_redge = TRUE; -+ last_matching_redge = next_center; -+ } -+ } -+ -+ next_center++; -+ } -+ -+ if (stem_matches > 0 ) valid_center_average /= stem_matches; -+ -+ best_height = stem_matches; -+ -+ /* new version */ -+ if ( ( stem_matches >= stem_match_requirement -+ || ( ( (FT_Int)bitmap->rows <= 6 || ppem < 11) -+ && stem_matches >= 2 -+ && abs(valid_center_average - centers[center].x) < deviation1 /2 ) -+ /* try to catch tightly aligned stuff where the matching centers are next to each other only */ -+ || ( stem_matches == 2 -+ && abs(valid_center_average - centers[center].x) <= deviation1 /2 -+ && no_gap_found && ppem < 18 ) /* catches things like times 16 u but gets a lot of w's too */ -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */ -+ ) -+ && -+ ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) ) -+ { -+ stem_detected = TRUE; -+ set_width_to = centers[center].x2 - centers[center].x1; -+ best_height = stem_matches; -+ set_center_to = centers[center].x; -+ -+ } -+ /* see if edges found anything */ -+ if (strategy_also_use_edge_detection_for_stems && !stem_detected) -+ { -+ if (( -+ /* Require no gap for edges */ -+ stem_matches_ledge >= stem_match_requirement && no_gap_found_ledge -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */ -+ ) && ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel) -+ /* The stem occurs on the left side of glyph only */ -+ && centers[center].x < (m_horiAdvance * 12) / 2 -+ -+ ) -+ { -+ stem_detected = TRUE; -+ set_width_to = smallest_width_ledge; -+ best_height = stem_matches_ledge; -+ set_center_to = centers[center].x1 + set_width_to / 2; -+ stem_matches = stem_matches_ledge; -+ } -+ else if (( -+ /* Require no gap for edges */ -+ stem_matches_redge >= stem_match_requirement && no_gap_found_redge -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */ -+ ) && ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel) -+ /* The stem occurs on the right side of glyph only */ -+ && centers[center].x > (m_horiAdvance * 12) / 2 -+ ) -+ { -+ stem_detected = TRUE; -+ set_width_to = smallest_width_redge; -+ best_height = stem_matches_redge; -+ set_center_to = centers[center].x2 - set_width_to / 2; -+ stem_matches = stem_matches_redge; -+ } -+ } -+ -+ -+ /*store and/or replace highest occurrences with 3 or more centers */ -+ /* because this matched, it will become the top dog regardless */ -+ if ( stem_detected ) -+ if ( stem_matches > possible_stems[0].height ) -+ { -+ /* if this is the first stem just go ahead */ -+ if (valid_possible_stems == 0) -+ { -+ valid_possible_stems = 1; -+ possible_stems[0].center = set_center_to; -+ possible_stems[0].count = stem_matches; -+ possible_stems[0].width = set_width_to; -+ possible_stems[0].height = stem_matches; -+ } -+ -+ /* otherwise, if there is already a stem */ -+ else if (valid_possible_stems == 1 ) -+ { -+ /* if the stem is within the range of existing one, replace existing one */ -+ -+ /* if the stem isn't within the range of this one swap it with next one first */ -+ if (abs(set_center_to - possible_stems[0].center) >= one_pixel * 2) -+ { -+ swap_stem ( &possible_stems[0], &possible_stems[1] ); -+ valid_possible_stems = 2; -+ } -+ possible_stems[0].center = set_center_to; -+ possible_stems[0].count = stem_matches; -+ possible_stems[0].width = set_width_to; -+ possible_stems[0].height = stem_matches; -+ } -+ -+ /* otherwise if there are already 2 stems */ -+ else if (valid_possible_stems >= 2 ) -+ { -+ /* if the stem is within the range of existing one, replace existing one */ -+ if ( abs(set_center_to - possible_stems[0].center) <= one_pixel * 2) -+ { -+ possible_stems[0].center = set_center_to; -+ possible_stems[0].count = stem_matches; -+ possible_stems[0].width = set_width_to; -+ possible_stems[0].height = stem_matches; -+ } -+ /* if the stem isn't within the range of this one */ -+ else -+ { -+ /* see if within range of next one and swap if so and proceed overwriting it */ -+ if ( abs(set_center_to - possible_stems[1].center) <= one_pixel * 2) -+ { -+ swap_stem ( &possible_stems[0], &possible_stems[1] ); -+ } -+ -+ /* otherwise see if in range of third one */ -+ else if ( abs(set_center_to - possible_stems[2].center) <= one_pixel * 2) -+ { -+ swap_stem ( &possible_stems[0], &possible_stems[2] ); -+ } -+ -+ /* otherwise this is the new top dog, so demote everything */ -+ else -+ { -+ swap_stem ( &possible_stems[1], &possible_stems[2] ); -+ swap_stem ( &possible_stems[0], &possible_stems[1] ); -+ valid_possible_stems += 1; -+ } -+ possible_stems[0].center = set_center_to; -+ possible_stems[0].count = stem_matches; -+ possible_stems[0].width = set_width_to; -+ possible_stems[0].height = stem_matches; -+ } -+ } -+ } -+ -+ else if ( stem_matches > possible_stems[1].height && set_center_to != 0) -+ { -+ -+ /* make sure it doesn't match the first stem */ -+ if ( abs(set_center_to - possible_stems[0].center) >= one_pixel * 2 ) -+ { -+ -+ /* if this is the second stem */ -+ if (valid_possible_stems == 1) valid_possible_stems = 2; -+ -+ /* otherwise if there is already a stem here */ -+ else if (valid_possible_stems >= 2 ) -+ { -+ /* if it doesn't match the second stem, proceed to swap out with the third */ -+ /* if it does, replace it */ -+ if ( abs(set_center_to - possible_stems[1].center) >= one_pixel * 2 ) -+ { -+ swap_stem ( &possible_stems[1], &possible_stems[2] ); -+ valid_possible_stems +=1; -+ } -+ } -+ possible_stems[1].center = set_center_to; -+ possible_stems[1].count = stem_matches; -+ possible_stems[1].width = set_width_to; -+ possible_stems[1].height = stem_matches; -+ } -+ } -+ -+ else if ( stem_matches > possible_stems[2].height && set_center_to != 0) -+ { -+ /* if it doesn't match the first or second one */ -+ if ( abs(set_center_to - possible_stems[0].center) >= one_pixel * 2 -+ && abs(set_center_to - possible_stems[1].center) >= one_pixel * 2) -+ -+ { -+ if (valid_possible_stems == 2) -+ { -+ valid_possible_stems += 1; -+ } -+ possible_stems[2].center = set_center_to; -+ possible_stems[2].count = stem_matches; -+ possible_stems[2].width = set_width_to; -+ possible_stems[1].height = stem_matches; -+ } -+ } -+ if (valid_possible_stems > 3) valid_possible_stems = 3; -+ -+ center++; -+ } -+ -+ /* promote to stem */ -+ if (valid_possible_stems > 0) -+ { -+ stems[0].center = possible_stems[0].center; -+ stems[0].count = possible_stems[0].count; -+ stems[0].width = possible_stems[0].width; -+ stems[0].height = possible_stems[0].height; -+ stems[0].generated = FALSE; -+ valid_stems++; -+ } -+ -+ if (valid_stems == 1 && valid_possible_stems > 1) -+ { -+ stems[1].center = possible_stems[1].center; -+ stems[1].count = possible_stems[1].count; -+ stems[1].width = possible_stems[1].width; -+ stems[1].height = possible_stems[1].height; -+ stems[1].generated = FALSE; -+ valid_stems++; -+ } -+ -+ if (valid_stems == 2 && valid_possible_stems > 2 && possible_stems[2].center != 0 ) -+ { -+ stems[2].center = possible_stems[2].center; -+ stems[2].count = possible_stems[2].count; -+ stems[2].width = possible_stems[2].width; -+ stems[2].height = possible_stems[2].height; -+ stems[2].generated = FALSE; -+ valid_stems++; -+ } -+ -+ /* sort stems in x direction */ -+ if ( valid_stems == 3) -+ { -+ if (stems[0].center > stems[1].center) -+ swap_stem ( &stems[0], &stems[1] ); -+ if (stems[0].center > stems[2].center) -+ swap_stem ( &stems[1], &stems[2] ); -+ if (stems[1].center > stems[2].center) -+ swap_stem ( &stems[1], &stems[2] ); -+ if (stems[0].center > stems[1].center) -+ swap_stem ( &stems[0], &stems[1] ); -+ -+ /* only look at first and last stem for now */ -+ swap_stem ( &stems[1], &stems[2] ); -+ } -+ -+ if (strategy_use_verdana_12_hack -+ && strcasestr(slot->face->family_name, "Verdana") -+ && ppem == 12 -+ && valid_stems == 1 -+ && (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4 -+ ||stems[0].center + m_horiBearingX * 12 - one_pixel > m_horiAdvance * 8) ) -+ { -+ if (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4) -+ { -+ stems[1].center = rightmost_point - one_pixel / 2; -+ stems[1].width = 1; -+ stems[1].generated = TRUE; -+ valid_stems += 1; -+ } -+ else -+ { -+ stems[1].center = leftmost_point + one_pixel / 2; -+ stems[1].width = 1; -+ stems[1].generated = TRUE; -+ valid_stems += 1; -+ } -+ strategy_always_use_distance_ceiling = TRUE; -+ } -+ -+ /* synthesize stems - Works, but needs work */ -+ if ( (strategy_synthesize_stems || known_stem_values->synth_stems) && valid_stems == 0 && ppem > 10 ) -+ { -+ /* if the leftmost segment's leftmost point is the same as the glyph's leftmost point, and it is of reasonable width, and is not on the top or bottom of the bitmap */ -+ if (leftmost_segment_not_extrema->x1 == leftmost_point_not_extrema -+ && abs(leftmost_segment_not_extrema->x2 - leftmost_segment_not_extrema->x1) -+ < (rightmost_point_not_extrema - leftmost_point_not_extrema)/3 -+ && leftmost_segment_not_extrema->y -+ < height && leftmost_segment_not_extrema->y > 1 ) -+ { -+ stems[valid_stems].center = (leftmost_segment_not_extrema->x2 + leftmost_segment_not_extrema->x1) / 2; -+ stems[valid_stems].width = leftmost_segment_not_extrema->x2 - leftmost_segment_not_extrema->x1; -+ stems[valid_stems].generated = TRUE; -+ valid_stems += 1; -+ } -+ -+ -+ if (rightmost_segment_not_extrema->x2 == rightmost_point_not_extrema -+ && abs(rightmost_segment_not_extrema->x2 - rightmost_segment_not_extrema->x1) -+ < (rightmost_point_not_extrema - leftmost_point_not_extrema)/3 -+ && rightmost_segment_not_extrema->y < height && rightmost_segment_not_extrema->y > 1 ) -+ { -+ stems[valid_stems].center = (rightmost_segment_not_extrema->x2 + rightmost_segment_not_extrema->x1) / 2; -+ stems[valid_stems].width = rightmost_segment_not_extrema->x2 - rightmost_segment_not_extrema->x1; -+ stems[valid_stems].generated = TRUE; -+ valid_stems += 1; -+ } -+ -+ } -+ -+ /* sort stems in x direction */ -+ if (valid_stems > 1 && stems[0].center > stems[1].center) -+ swap_stem ( &stems[0], &stems[1] ); -+ -+ if ( valid_stems == 0 && known_stem_values->stem_translating != 0 ) -+ { -+ *translate_value += known_stem_values->stem_translating; -+ -+ if (strategy_use_strengths ) -+ { -+ /* consider 1/2 pixel the max when strength is at 100%, unless translate is already greater than that */ -+ FT_Int strength_cutoff = 32; -+ if (abs(*translate_value) > strength_cutoff) strength_cutoff = *translate_value; -+ max_strength = (strength_cutoff * alignment_strength) / 100; -+ if (*translate_value < -max_strength) *translate_value = -max_strength; -+ else if (*translate_value > max_strength) *translate_value = max_strength; -+ } -+ } -+ else -+ /* Start snapping */ -+ { -+ FT_Int center_offset; -+ FT_Int modulus; -+ FT_Int delta, delta2; -+ FT_Long stem_distance = 1, new_distance = 1; -+ FT_Int distance_floor, distance_ceiling; -+ FT_Int translate_value2 = 0; -+ FT_Int main_stem = 0; -+ FT_Int lbearing = m_horiBearingX * 12; -+ FT_Int bitmap_stem_location = stems[0].center; -+ FT_Int advance_stem_location = bitmap_stem_location + lbearing - one_pixel; -+ FT_Int advance_width = m_horiAdvance * 12; -+ FT_Int original_advance_width = 12 * (slot->linearHoriAdvance >> 10); -+ FT_Int glyph_width = rightmost_point - leftmost_point; -+ FT_Int stem_width = stems[0].width; -+ FT_Int advance_leftmost_location = leftmost_point + lbearing - one_pixel; -+ FT_Int advance_rightmost_location = rightmost_point + lbearing - one_pixel; -+ -+#define proposed_transformed_point(point) \ -+ point * (float)(new_distance) / (float)(stem_distance) \ -+ + *translate_value * 12 - ( stems[main_stem].center * (float)(new_distance) \ -+ / (float)(stem_distance) - stems[main_stem].center) -+ -+#define proposed_translated_point(point) point + *translate_value * 12 -+ -+ center_offset = one_pixel / 2; /* half pixel */ -+ modulus = one_pixel; /* whole pixel */ -+ -+ /* Determine center_offset via known values */ -+ if (known_stem_values->stem_width >= 0) -+ { -+ if (known_stem_values->stem_width % 2 == 0) -+ { -+ center_offset = 0; -+ } -+ else -+ { -+ center_offset = one_pixel / 2; -+ } -+ } -+ /* otherwise do intelligent guessing, if set */ -+ else if ( strategy_auto_change_center_offset -+ && ppem >= STEM_WIDTH_2_PPEM -+ && stems[0].width < one_pixel * 1.45) -+ { -+ center_offset = one_pixel / 2; -+ } -+ else if ( strategy_auto_change_center_offset -+ && ppem >= STEM_WIDTH_2_PPEM -+ && stems[0].width >= one_pixel * 1.45 -+ && stems[0].width < one_pixel * 2.6) -+ { -+ center_offset = 0; -+ } -+ else if ( strategy_auto_change_center_offset -+ && ppem >= STEM_WIDTH_2_PPEM -+ && stems[0].width >= one_pixel * 2.6 -+ && stems[0].width < one_pixel * 3.6) -+ { -+ center_offset = one_pixel / 2; -+ } -+ else if ( strategy_auto_change_center_offset && ppem >= STEM_WIDTH_2_PPEM ) -+ center_offset = (one_pixel * ((((int)(stems[0].width + one_pixel / 2)) / one_pixel ) % 2) ) / 2; -+ -+ /* Snap to closest translate and scale values by default */ -+ if (valid_stems >= 1) -+ { -+ /* closest snapping point for stem 0 */ -+ delta = (stems[0].center + center_offset) % (modulus); -+ -+ if (delta < modulus / 2 ) *translate_value = ( - delta ) / (columns_per_pixel * 4); /* snap left */ -+ else *translate_value = (modulus -delta) / (columns_per_pixel * 4); /* snap right */ -+ } -+ -+ if (strategy_use_d_correction) -+ { -+ /* if the only stem is in the last 1/3 of glyph width, the advance is -+ * 6 pixels, the ppem 11, and doing so doesn't violate bitmap boundaries, -+ * force it to snap right */ -+ if (valid_stems == 1 && advance_stem_location > (advance_width * 2) / 3 -+ && advance_width == 6 * one_pixel -+ && rightmost_point + modulus - delta <= ( width - (columns_per_pixel * 2) / 3) * 256 -+ && ppem == 11 -+ ) -+ *translate_value = (modulus -delta) / (columns_per_pixel * 4); -+ } -+ -+ if (strategy_use_strengths ) -+ { -+ /* consider 1/2 pixel the max when strength is at 100%, unless translate is already greater than that */ -+ FT_Int strength_cutoff = 32; -+ if (abs(*translate_value) > strength_cutoff) strength_cutoff = *translate_value; -+ max_strength = (strength_cutoff * alignment_strength) / 100; -+ if (*translate_value < -max_strength) *translate_value = -max_strength; -+ else if (*translate_value > max_strength) *translate_value = max_strength; -+ } -+ -+ /* If 2 stems is detected, scale distance between in order to land on pixels */ -+ if ( valid_stems >= 2) -+ { -+ stem_distance = abs(stems[1].center - stems[0].center); -+ -+ delta = stem_distance % ( modulus ); -+ new_distance = stem_distance - delta; -+ -+ distance_floor = stem_distance - delta; -+ distance_ceiling = stem_distance + (modulus - delta); -+ -+ if (delta < modulus / 2 ) new_distance = distance_floor; -+ else new_distance = distance_ceiling; -+ -+ if ( columns_per_pixel == 3 && valid_stems == 3 && strategy_use_m_control && valid_stems == 3 -+ && (width - 2 * columns_per_pixel) > 6 * columns_per_pixel -+ && ppem > 8 -+ && (advance_stem_location - advance_leftmost_location) < stems[main_stem].width * 2 ) -+ { -+ FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */ -+ -+ if (verbose) printf ("USING M CONTROL "); -+ distance_floor = stem_distance - stem_distance % ( modulus * mod_factor) ; -+ distance_ceiling = distance_floor + modulus * mod_factor; -+ -+ new_distance = distance_ceiling; -+ -+ /* force certain ideal situations */ -+ /* these 2 are mostly safe to do */ -+ if (distance_ceiling + one_pixel * columns_per_pixel == advance_width -+ && (stem_width < one_pixel * 1.25 )) -+ new_distance = distance_ceiling; -+ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER THAT NUDGE IS UP OR DOWN */ -+ else if (stem_distance + one_pixel * 2.6 >= advance_width -+ && (stem_width < one_pixel * 1.25 )) -+ new_distance = distance_ceiling; -+ -+ if (proposed_transformed_point(leftmost_point) < one_third_pixel * 2 -+ || proposed_transformed_point(rightmost_point) > (width -2 ) * one_third_pixel) -+ new_distance = distance_floor; -+ -+ /* NEED TO IGNORE SERIF Ms HERE */ -+ /* perhaps check bitmap boundaries instead??? */ -+ if (strategy_bearing_correction && new_distance == distance_ceiling) -+ { -+ /* Correct if bearings are made substantially worse (more than 1/3 a pixel beyond advance) */ -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width + one_third_pixel -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width -+ ) -+ new_distance = distance_floor; -+ } -+ -+ if ( known_stem_values->m >= 0 ) -+ { -+ if ( known_stem_values->m == 0 ) new_distance = distance_floor; -+ else new_distance = distance_ceiling; -+ } -+ -+ if ( (rightmost_point - leftmost_point) - ((rightmost_point * *scale_value) - (leftmost_point * *scale_value)) >= one_pixel * 1.5 ) -+ { -+ *scale_value = 1.0; -+ *translate_value = 0; -+ goto Exit; -+ } -+ -+ } -+ else if ( columns_per_pixel == 1 && valid_stems == 3 && strategy_use_m_control && valid_stems == 3 -+ && width >= 6 * columns_per_pixel -+ && ppem > 8 -+ && (advance_stem_location - advance_leftmost_location) < stems[main_stem].width * 2 ) -+ { -+ FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */ -+ -+ if (verbose) printf ("USING M CONTROL "); -+ distance_floor = stem_distance - stem_distance % ( modulus * mod_factor) ; -+ distance_ceiling = distance_floor + modulus * mod_factor; -+ -+ new_distance = distance_ceiling; -+ -+ /* force certain ideal situations */ -+ /* these 2 are mostly safe to do */ -+ if (distance_ceiling + one_pixel * columns_per_pixel == advance_width -+ && (stem_width < one_pixel * 1.25 )) new_distance = distance_ceiling; -+ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER THAT NUDGE IS UP OR DOWN */ -+ else if (stem_distance + one_pixel * 2.6 >= advance_width -+ && (stem_width < one_pixel * 1.25 )) -+ new_distance = distance_ceiling; -+ -+ if (proposed_transformed_point(leftmost_point) < 0 -+ || proposed_transformed_point(rightmost_point) > (width) * one_pixel - 2*one_third_pixel) -+ new_distance = distance_floor; -+ -+ /* NEED TO IGNORE SERIF Ms HERE */ -+ /* perhaps check bitmap boundaries instead??? */ -+ if (strategy_bearing_correction && new_distance == distance_ceiling) -+ { -+ /* Correct if bearings are made substantially worse (more than 1/3 a pixel beyond advance) */ -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width + one_third_pixel -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width -+ ) -+ new_distance = distance_floor; -+ } -+ -+ if ( known_stem_values->m >= 0 ) -+ { -+ if ( known_stem_values->m == 0 ) new_distance = distance_floor; -+ else new_distance = distance_ceiling; -+ } -+ -+ -+ if ( (rightmost_point - leftmost_point) - ((rightmost_point * *scale_value) - (leftmost_point * *scale_value)) >= one_pixel * 1.5 ) -+ { -+ *scale_value = 1.0; -+ *translate_value = 0; -+ goto Exit; -+ } -+ -+ } -+ else -+ { -+ if (strategy_fit_to_width) -+ { -+ new_distance = advance_width - 3 * one_pixel; -+ } -+ else if (known_stem_values->stem_scaling >= 0) -+ { -+ if (known_stem_values->stem_scaling > 0) new_distance = distance_ceiling; -+ else new_distance = distance_floor; -+ -+ /* enforce advance width boundaries */ -+ /* TOO RESTRICTIVE ON SERIF FONTS */ -+ if ( proposed_transformed_point(advance_rightmost_location) >= advance_width -+ || proposed_transformed_point(advance_leftmost_location) <= 0 -+ ) new_distance = distance_floor; -+ -+ /* enforce literal bitmap boundaries if there is no translate room */ -+ if ( ( proposed_transformed_point(rightmost_point) >= width * 256 -+ || proposed_transformed_point(leftmost_point ) <= one_pixel ) -+ && new_distance + one_pixel * 3 > advance_width ) -+ new_distance = distance_floor; -+ -+ } -+ else if (strategy_translate_using_closest_stem) -+ { -+ /* closest snapping point for stem 1 */ -+ delta2 = (stems[1].center + center_offset) % (modulus); -+ -+ if (delta2 < modulus / 2 ) translate_value2 = ( - delta2 ) / (columns_per_pixel * 4); /* snap left */ -+ else translate_value2 = (modulus -delta2) / (columns_per_pixel * 4); /* snap right */ -+ -+ if (abs(translate_value2) < abs(*translate_value)) -+ { -+ *translate_value = translate_value2; -+ main_stem = 1; -+ } -+ -+ } -+ else if (strategy_scale_to_closest_centers) -+ { -+ /* closest snapping point for stem 0 */ -+ delta = (stems[0].center + center_offset) % (modulus); -+ delta2 = (stems[1].center + center_offset) % (modulus); -+ -+ if (delta < modulus / 2 ) new_distance = delta + stem_distance; /* stretch left */ -+ else new_distance = delta - modulus + stem_distance; /* stretch right */ -+ -+ if (delta2 < modulus / 2 ) new_distance -= delta2; /* stretch left */ -+ else new_distance += modulus - delta2; /* stretch right */ -+ -+ } -+ else if (strategy_scale_to_closest_centers_up_only) -+ { -+ FT_Int net_change = 0; -+ -+ /* closest snapping point for stem 0 */ -+ delta = (stems[0].center + center_offset) % (modulus); -+ delta2 = (stems[1].center + center_offset) % (modulus); -+ -+ if (delta < modulus / 2 ) net_change = delta; /* stretch left */ -+ else net_change = -(modulus - delta); /* stretch right */ -+ -+ if (delta2 < modulus / 2 ) net_change -= delta2; /* stretch left */ -+ else net_change += modulus - delta2; /* stretch right */ -+ -+ if (net_change > 0 -+ && proposed_transformed_point(advance_rightmost_location) < advance_width -+ && proposed_transformed_point(advance_leftmost_location) > 0 -+ ) new_distance = distance_ceiling; -+ } -+ -+ else if (strategy_always_use_distance_ceiling) -+ { -+ if ( proposed_transformed_point(advance_rightmost_location) < advance_width -+ && proposed_transformed_point(advance_leftmost_location) > 0 -+ ) -+ new_distance = distance_ceiling; -+ } -+ } -+ -+ if (strategy_use_strengths) -+ { -+ FT_Int strength_cutoff = center_offset; -+ delta2 = new_distance - stem_distance; -+ if (abs(delta2) > strength_cutoff) strength_cutoff = delta2; -+ -+ max_strength = (strength_cutoff * fitting_strength) / 100; -+ if (delta2 < -max_strength ) new_distance = stem_distance - max_strength; -+ else if (delta2 > max_strength) new_distance = stem_distance + max_strength; -+ } -+ -+ *scale_value = (float)(new_distance + 0) / (float)(stem_distance + 0 ); -+ *translate_value = *translate_value - ((float)(stems[main_stem].center * (float)new_distance) / (float)stem_distance - stems[main_stem].center) / 12; - -- return 0; -- } -+ if (valid_stems == 2) *embolden_value = (64.0 / *scale_value - 64.0); -+ if (valid_stems == 3) *embolden_value = (64.0 / *scale_value - 64.0) / 1.5; -+ } - -+ if (verbose) printf ("%lu stems:", valid_stems); - -- /* sets render-specific mode */ -- static FT_Error -- ft_smooth_set_mode( FT_Renderer render, -- FT_ULong mode_tag, -- FT_Pointer data ) -- { -- /* we simply pass it to the raster */ -- return render->clazz->raster_class->raster_set_mode( render->raster, -- mode_tag, -- data ); -- } -+ if (valid_stems == 1 && verbose) -+ printf ("1 stem: bitmapwidth:%d glyphwidth:%f glyph_width:%f center:%f bearing:%f advance:%f lhadvance:%f stemwidth:%f %d %d", -+ (width - 6) / columns_per_pixel, -+ (float)m_width / 64.0, -+ (float)glyph_width / (float)one_pixel, -+ (float)((float)advance_stem_location) / (float)one_pixel, -+ (float)m_horiBearingX / 64.0, -+ (float)m_horiAdvance / 64.0, -+ (float)linearHoriAdvance / 64.0, -+ (float)stems[0].width / (float)one_pixel, -+ advance_width, original_advance_width -+ ); -+ else if (valid_stems >= 2 && verbose) -+ printf ("%lu stems: bitmapwidth:%d center1:%f center2:%f difference:%f bearing:%f advance:%f advstemloc:%f ", -+ valid_stems, -+ (width - 6) / columns_per_pixel, -+ ((float)advance_stem_location) / (float)one_pixel, -+ ((float)advance_stem_location + (float)abs(stems[1].center - stems[0].center)) / (float)one_pixel, -+ ((float)abs(stems[1].center - stems[0].center)) / (float)one_pixel, -+ (float)m_horiBearingX / 64.0, -+ (float)m_horiAdvance / 64.0, -+ (float)advance_stem_location / (float)one_pixel); - -- /* transform a given glyph image */ -- static FT_Error -- ft_smooth_transform( FT_Renderer render, -- FT_GlyphSlot slot, -- const FT_Matrix* matrix, -- const FT_Vector* delta ) -- { -- FT_Error error = Smooth_Err_Ok; -+ if (strategy_bearing_correction) -+ { -+ /* Correct if negative bearings are made substantially worse (more than 1/3 a pixel) */ -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width -+ && *translate_value > one_third_pixel / (columns_per_pixel * 4) ) -+ { -+ *translate_value -=64 ; -+ if (verbose) printf ("TRANSLATING -64 "); -+ } -+ } - -+ if ( strategy_use_verdana_12_hack -+ && strcasestr(slot->face->family_name, "Verdana") -+ && ppem == 12 -+ && *scale_value == 1.0 && valid_stems == 0 -+ && height < 8 -+ && advance_rightmost_location * 1.1 < advance_width ) -+ *scale_value = 1.1; - -- if ( slot->format != render->glyph_format ) -- { -- error = Smooth_Err_Invalid_Argument; - goto Exit; -+ - } - -- if ( matrix ) -- FT_Outline_Transform( &slot->outline, matrix ); -+ Exit: - -- if ( delta ) -- FT_Outline_Translate( &slot->outline, delta->x, delta->y ); -+#define transformed_point( point ) point * *scale_value + *translate_value * 12 -+ -+ if (strategy_correct_out_of_bounds_outlines) -+ { -+ /* Correct if outside bitmap */ -+ if (transformed_point(rightmost_point) >= width * 256 - 2 * one_third_pixel -+ && transformed_point(leftmost_point ) > one_pixel + 2 * one_third_pixel ) -+ { -+ *translate_value -=64 ; -+ } -+ else if (transformed_point(leftmost_point) <= one_pixel / 2 -+ && transformed_point(rightmost_point ) <= width * 256 -(one_pixel + one_pixel / 2) ) -+ { -+ *translate_value += 64; -+ } -+ } -+ -+ STVALUES -+ -+ free(segments); -+ free(leftmost_segment); -+ free(rightmost_segment); -+ -+ free(known_stem_values); -+ free(stems); -+ free(possible_stems); -+ free(leftmost_stem); -+ free(rightmost_stem); -+ -+ free(centers); - -- Exit: -- return error; - } - - -- /* return the glyph's control box */ -+ /* Gamma correction */ - static void -- ft_smooth_get_cbox( FT_Renderer render, -- FT_GlyphSlot slot, -- FT_BBox* cbox ) -+ _ft_lcd_gamma_correction_correction ( FT_Bitmap* bitmap, -+ FT_Render_Mode mode, -+ FT_GlyphSlot slot, -+ float gamma_correction_lt, -+ float gamma_correction_value) - { -- FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); -- -- if ( slot->format == render->glyph_format ) -- FT_Outline_Get_CBox( &slot->outline, cbox ); -+ if ( gamma_correction_value != 1.0 ) -+ { -+ FT_UInt width = (FT_UInt)bitmap->width; -+ FT_UInt height = (FT_UInt)bitmap->rows; -+ FT_Byte* line = bitmap->buffer; -+ float ppem = (float)slot->face->size->metrics.x_ppem; -+ -+ if ( !slot->face || !slot->face->size ) return; -+ -+ if (ppem >= 5 ) -+ for (height = (FT_UInt)bitmap->rows; height > 0; height--, line += bitmap->pitch ) -+ { -+ FT_UInt xx; -+ -+ for ( xx = 0; xx < width; xx += 1 ) -+ { -+ /*normal*/ -+ /*line[xx] = gamma2 ( line[xx], gamma_correction_value );*/ -+ -+ /* sloped */ -+ /*line[xx] = gamma2 ( line[xx], gamma_correction_value - 5 -+ * (1-gamma_correction_value)/(gamma_correction_lt -5) -+ + ((1-gamma_correction_value)/(gamma_correction_lt -5)) * ppem );*/ -+ -+ /* 1/3-sloped */ -+ line[xx] = gamma2 ( line[xx], gamma_correction_value - 5 -+ * ((1-gamma_correction_value)/(3*(gamma_correction_lt -5))) -+ * + ((1-gamma_correction_value)/(3*(gamma_correction_lt -5))) * ppem ); -+ } -+ } -+ } - } - -+#endif -+ - - /* convert a slot's glyph image into a bitmap */ - static FT_Error -@@ -104,19 +2871,406 @@ - { - FT_Error error; - FT_Outline* outline = NULL; -+ FT_Outline* outline_orig = NULL; - FT_BBox cbox; -- FT_Pos width, height, pitch; -+ FT_Pos width=0, height=0, pitch=0, ppem; - #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - FT_Pos height_org, width_org; - #endif -- FT_Bitmap* bitmap; -- FT_Memory memory; -+ FT_Bitmap* bitmap = 0; -+ FT_Memory memory = 0; - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; -- FT_Pos x_shift, y_shift, x_left, y_top; -+ FT_Pos x_shift = 0, y_shift = 0, x_left = 0, y_top = 0; - - FT_Raster_Params params; - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ FT_Matrix scaleMat; -+ FT_Long translate_value = 0; -+ float scale_value = 1.0; -+ FT_Int align_called = 0; -+ -+ -+ int chromeos_style_sharpening_strength = 0; -+ int checked_chromeos_style_sharpening_strength = 0; -+ int alignment_strength = 0; -+ int fitting_strength = 0; -+ FT_UInt checked_alignment_strength = 0; -+ FT_UInt checked_fitting_strength = 0; -+ FT_UInt checked_fringe_filter_strength = 0; -+ int fringe_filter_strength = 0; -+ FT_UInt checked_grayscale_filter_strength = 0; -+ int grayscale_filter_strength = 0; -+ -+ FT_UInt checked_autohint_horizontal_stem_darken_strength = 0; -+ int autohint_horizontal_stem_darken_strength = 0; -+ -+ FT_UInt checked_autohint_vertical_stem_darken_strength = 0; -+ int autohint_vertical_stem_darken_strength = 0; -+ -+ int windows_style_sharpening_strength = 0; -+ FT_UInt checked_windows_style_sharpening_strength = 0; -+ float gamma_correction_value = 1; -+ float gamma_correction_lt = 0; -+ FT_UInt checked_gamma_correction_value = 0; -+ -+ FT_Int brightness_value = 0.0; -+ FT_UInt checked_brightness_value = 0; -+ -+ FT_Int contrast_value = 0.0; -+ FT_UInt checked_contrast_value = 0; -+ -+ FT_Int snapping_sliding_scale_value = 0; -+ FT_UInt checked_snapping_sliding_scale_value = 0; -+ -+ FT_Int global_embolden_x_value = 0; -+ FT_UInt checked_global_embolden_x_value = 0; -+ -+ FT_Int global_embolden_y_value = 0; -+ FT_UInt checked_global_embolden_y_value = 0; -+ -+ FT_Int bold_embolden_x_value = 0; -+ FT_UInt checked_bold_embolden_x_value = 0; -+ -+ FT_Int bold_embolden_y_value = 0; -+ FT_UInt checked_bold_embolden_y_value = 0; -+ -+ FT_Byte chromeos_cutoff; -+ double chromeos_gamma_value; -+ -+ float embolden_value = 0.0; -+ FT_Bool autohinted = FALSE; -+ -+ FT_UInt autohint_minimum_stem_height = 0; -+ FT_UInt checked_autohint_minimum_stem_height = 0; -+ -+ int checked_use_various_tweaks_env = 0; -+ FT_Bool use_various_tweaks = FALSE; -+ -+ int cur_width; -+ char *cur_width_env = getenv( "CUR_WIDTH" ); -+ -+ const FT_Int MIN_PPEM = 1; -+ /*const FT_Int MAX_PPEM = 100; */ -+ -+ int checked_use_known_settings_on_selected_fonts_env = 0; -+ FT_Bool use_known_settings_on_selected_fonts = FALSE; -+ -+ if ( slot->face && slot->face->size && slot->face->size->metrics.x_ppem ) -+ ppem = slot->face->size->metrics.x_ppem; -+ else ppem = 0; -+ -+ if ( cur_width_env != NULL ){ -+ sscanf ( cur_width_env, "%d", &cur_width ); -+ if (cur_width != 0) autohinted = TRUE; -+ } -+ -+ if ( checked_use_known_settings_on_selected_fonts_env == 0 ) -+ { -+ char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" ); -+ if ( use_known_settings_on_selected_fonts_env != NULL ) -+ { -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0) -+ use_known_settings_on_selected_fonts = TRUE; -+ } -+ } -+ checked_use_known_settings_on_selected_fonts_env = 1; -+ } -+ -+ if ( checked_use_various_tweaks_env == 0 ) -+ { -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" ); -+ if ( use_various_tweaks_env != NULL ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 ) -+ { -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) -+ use_various_tweaks = TRUE; -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) -+ use_various_tweaks = TRUE; -+ } -+ } -+ checked_use_various_tweaks_env = 1; -+ } -+ -+ if ( checked_autohint_minimum_stem_height == 0) -+ { -+ char *autohint_minimum_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_MINIMUM_STEM_WIDTH" ); -+ if ( autohint_minimum_stem_height_env != NULL ) -+ { -+ sscanf ( autohint_minimum_stem_height_env, "%u", &autohint_minimum_stem_height ); -+ if (autohint_minimum_stem_height > 100 ) autohint_minimum_stem_height = 100; -+ else if (autohint_minimum_stem_height < 0 ) autohint_minimum_stem_height = 0; -+ } -+ checked_autohint_minimum_stem_height = 1; -+ } -+ -+ if ( checked_snapping_sliding_scale_value == 0) -+ { -+ char *snapping_sliding_scale_env = getenv ( "INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE" ); -+ if ( snapping_sliding_scale_env != NULL ) -+ { -+ sscanf ( snapping_sliding_scale_env, "%d", &snapping_sliding_scale_value ); -+ if (snapping_sliding_scale_value > MAX_PPEM ) snapping_sliding_scale_value = 0; -+ else if (snapping_sliding_scale_value < 0 ) snapping_sliding_scale_value = 0; -+ -+ if (snapping_sliding_scale_value < 11 && snapping_sliding_scale_value > 0 ) snapping_sliding_scale_value = 11; -+ } -+ checked_snapping_sliding_scale_value = 1; -+ } -+ -+ if ( checked_alignment_strength == 0) -+ { -+ char *alignment_strength_env = getenv ( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" ); -+ if ( alignment_strength_env != NULL ) -+ { -+ sscanf ( alignment_strength_env, "%d", &alignment_strength ); -+ if (alignment_strength > 100 ) alignment_strength = 100; -+ else if (alignment_strength < 0 ) alignment_strength = 0; -+ } -+ if (alignment_strength > 100 ) alignment_strength = 100; -+ checked_alignment_strength = 1; -+ if (snapping_sliding_scale_value != 0) -+ alignment_strength = sliding_scale ( 10, snapping_sliding_scale_value, alignment_strength, 100, ppem); -+ } -+ -+ if ( checked_fitting_strength == 0) -+ { -+ char *fitting_strength_env = getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" ); -+ if ( fitting_strength_env != NULL ) -+ { -+ sscanf ( fitting_strength_env, "%d", &fitting_strength ); -+ if (fitting_strength > 100 ) fitting_strength = 100; -+ else if (fitting_strength < 0 ) fitting_strength = 0; -+ } -+ if (fitting_strength > 100 ) fitting_strength = 100; -+ checked_fitting_strength = 1; -+ if (snapping_sliding_scale_value != 0) -+ fitting_strength = sliding_scale ( 10, snapping_sliding_scale_value, fitting_strength, 100, ppem); -+ } -+ -+ if ( checked_chromeos_style_sharpening_strength == 0) -+ { -+ char *chromeos_style_sharpening_strength_env = getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" ); -+ if ( chromeos_style_sharpening_strength_env != NULL ) -+ { -+ sscanf ( chromeos_style_sharpening_strength_env, "%d", &chromeos_style_sharpening_strength ); -+ if (chromeos_style_sharpening_strength > 100 ) -+ chromeos_style_sharpening_strength = 100; -+ else if (chromeos_style_sharpening_strength < 0 ) -+ chromeos_style_sharpening_strength = 0; -+ } -+ if (ppem > 10) -+ chromeos_style_sharpening_strength = -+ (chromeos_style_sharpening_strength * ppem) / 10; -+ if (chromeos_style_sharpening_strength > 100 ) -+ chromeos_style_sharpening_strength = 100; -+ checked_chromeos_style_sharpening_strength = 1; -+ } -+ -+ -+ if ( checked_brightness_value == 0) -+ { -+ char *brightness_env = getenv( "INFINALITY_FT_BRIGHTNESS" ); -+ if ( brightness_env != NULL ) -+ { -+ sscanf ( brightness_env, "%d", &brightness_value ); -+ if (brightness_value > 100 ) -+ brightness_value = 100; -+ else if (brightness_value < -100 ) -+ brightness_value = 0; -+ } -+ checked_brightness_value = 1; -+ } -+ -+ if ( checked_contrast_value == 0) -+ { -+ char *contrast_env = getenv( "INFINALITY_FT_CONTRAST" ); -+ if ( contrast_env != NULL ) -+ { -+ sscanf ( contrast_env, "%d", &contrast_value ); -+ if (contrast_value > 100 ) -+ contrast_value = 100; -+ else if (contrast_value < -100 ) -+ contrast_value = 100; -+ } -+ checked_contrast_value = 1; -+ } -+ -+ if ( checked_windows_style_sharpening_strength == 0) -+ { -+ char *windows_style_sharpening_strength_env = getenv( "INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH" ); -+ if ( windows_style_sharpening_strength_env != NULL ) -+ { -+ sscanf ( windows_style_sharpening_strength_env, "%d", &windows_style_sharpening_strength ); -+ if (windows_style_sharpening_strength > 100 ) windows_style_sharpening_strength = 100; -+ else if (windows_style_sharpening_strength < 0 ) windows_style_sharpening_strength = 0; -+ } -+ /* Decrease the effect slightly in order to have a more linear increase in sharpness */ -+ windows_style_sharpening_strength = -+ (( windows_style_sharpening_strength * windows_style_sharpening_strength ) / 100 + windows_style_sharpening_strength) / 2; -+ checked_windows_style_sharpening_strength = 1; -+ } -+ -+ if ( checked_gamma_correction_value == 0 ) -+ { -+ char *gamma_correction_value_env = getenv( "INFINALITY_FT_GAMMA_CORRECTION" ); -+ if ( gamma_correction_value_env != NULL ) -+ { -+ float f1, f2; -+ -+ if ( strcasecmp(gamma_correction_value_env, "default" ) != 0) -+ { -+ sscanf ( gamma_correction_value_env, "%f %f", &f1, &f2 ); -+ gamma_correction_lt = f1; -+ gamma_correction_value = f2 / 100.0; -+ } -+ if ( gamma_correction_value < .01 ) gamma_correction_value = 1.0; -+ } -+ checked_gamma_correction_value = 1; -+ } -+ -+ /* set gamma value to 1 if out of range */ -+ if ( slot->face && slot->face->size && slot->face->size->metrics.x_ppem ) -+ { -+ if ( slot->face->size->metrics.x_ppem >= gamma_correction_lt ) -+ { -+ gamma_correction_value = 1; -+ } -+ } -+ else gamma_correction_value = 1; -+ -+ -+ if ( checked_fringe_filter_strength == 0) -+ { -+ char *fringe_filter_strength_env = getenv( "INFINALITY_FT_FRINGE_FILTER_STRENGTH" ); -+ if ( fringe_filter_strength_env != NULL ) -+ { -+ sscanf ( fringe_filter_strength_env, "%d", &fringe_filter_strength ); -+ if (fringe_filter_strength > 100 ) fringe_filter_strength = 100; -+ else if (fringe_filter_strength < 0 ) fringe_filter_strength = 0; -+ } -+ checked_fringe_filter_strength = 1; -+ } -+ -+ -+ if ( checked_grayscale_filter_strength == 0) -+ { -+ char *grayscale_filter_strength_env = getenv( "INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH" ); -+ if ( grayscale_filter_strength_env != NULL ) -+ { -+ sscanf ( grayscale_filter_strength_env, "%d", &grayscale_filter_strength ); -+ if (grayscale_filter_strength > 100 ) grayscale_filter_strength = 100; -+ else if (grayscale_filter_strength < 0 ) grayscale_filter_strength = 0; -+ } -+ checked_grayscale_filter_strength = 1; -+ } -+ -+ -+ if ( checked_autohint_horizontal_stem_darken_strength == 0) -+ { -+ char *autohint_horizontal_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH" ); -+ if ( autohint_horizontal_stem_darken_strength_env != NULL ) -+ { -+ sscanf ( autohint_horizontal_stem_darken_strength_env, "%d", &autohint_horizontal_stem_darken_strength ); -+ if (autohint_horizontal_stem_darken_strength > 100 ) autohint_horizontal_stem_darken_strength = 100; -+ else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_horizontal_stem_darken_strength = 0; -+ } -+ checked_autohint_horizontal_stem_darken_strength = 1; -+ } -+ -+ if ( checked_autohint_vertical_stem_darken_strength == 0) -+ { -+ char *autohint_vertical_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH" ); -+ if ( autohint_vertical_stem_darken_strength_env != NULL ) -+ { -+ sscanf ( autohint_vertical_stem_darken_strength_env, "%d", &autohint_vertical_stem_darken_strength ); -+ if (autohint_vertical_stem_darken_strength > 100 ) autohint_vertical_stem_darken_strength = 100; -+ else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_vertical_stem_darken_strength = 0; -+ } -+ checked_autohint_vertical_stem_darken_strength = 1; -+ } -+ -+ if ( checked_global_embolden_x_value == 0) -+ { -+ char *global_embolden_x_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE" ); -+ if ( global_embolden_x_env != NULL ) -+ { -+ sscanf ( global_embolden_x_env, "%d", &global_embolden_x_value ); -+ if (global_embolden_x_value > 128 ) global_embolden_x_value = 128; -+ else if (global_embolden_x_value < -128 ) global_embolden_x_value = -128; -+ } -+ checked_global_embolden_x_value = 1; -+ } -+ -+ if ( checked_global_embolden_y_value == 0) -+ { -+ char *global_embolden_y_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE" ); -+ if ( global_embolden_y_env != NULL ) -+ { -+ sscanf ( global_embolden_y_env, "%d", &global_embolden_y_value ); -+ if (global_embolden_y_value > 128 ) global_embolden_y_value = 128; -+ else if (global_embolden_y_value < -128 ) global_embolden_y_value = -128; -+ } -+ checked_global_embolden_y_value = 1; -+ } -+ -+ -+ if ( checked_bold_embolden_x_value == 0) -+ { -+ char *bold_embolden_x_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE" ); -+ if ( bold_embolden_x_env != NULL ) -+ { -+ sscanf ( bold_embolden_x_env, "%d", &bold_embolden_x_value ); -+ if (bold_embolden_x_value > 128 ) bold_embolden_x_value = 128; -+ else if (bold_embolden_x_value < -128 ) bold_embolden_x_value = -128; -+ -+ } -+ checked_bold_embolden_x_value = 1; -+ } -+ -+ if ( checked_bold_embolden_y_value == 0) -+ { -+ char *bold_embolden_y_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE" ); -+ if ( bold_embolden_y_env != NULL ) -+ { -+ sscanf ( bold_embolden_y_env, "%d", &bold_embolden_y_value ); -+ if (bold_embolden_y_value > 128 ) bold_embolden_y_value = 128; -+ else if (bold_embolden_y_value < -128 ) bold_embolden_y_value = -128; -+ -+ } -+ checked_bold_embolden_y_value = 1; -+ } -+ -+ -+ -+ if( use_various_tweaks && slot->face && slot->face->style_name ) -+ { -+ /* needs to also check for artifical italics */ -+ if ( strcasestr(slot->face->style_name, "Italic") -+ || strcasestr(slot->face->style_name, "Oblique") ) -+ { -+ windows_style_sharpening_strength = 0; -+ chromeos_style_sharpening_strength = 0; -+ } -+ } -+ -+ /*if (fitting_strength == 100) scale_value = 1.1;*/ -+ -+#endif - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) -@@ -129,92 +3283,174 @@ - if ( mode != required_mode ) - return Smooth_Err_Cannot_Render_Glyph; - -- outline = &slot->outline; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+RERENDER: -+ if (align_called == 1){ - -- /* translate the outline to the new origin if needed */ -- if ( origin ) -- FT_Outline_Translate( outline, origin->x, origin->y ); -+ scaleMat.xx = FT_FixedFromFloat(scale_value); -+ scaleMat.xy = 0; -+ scaleMat.yx = 0; -+ scaleMat.yy = (1 << 16); - -- /* compute the control box, and grid fit it */ -- FT_Outline_Get_CBox( outline, &cbox ); -+ FT_Outline_Copy(outline_orig, outline); - -- cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); -- cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); -- cbox.xMax = FT_PIX_CEIL( cbox.xMax ); -- cbox.yMax = FT_PIX_CEIL( cbox.yMax ); -- -- if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) -- { -- FT_ERROR(( "ft_smooth_render_generic: glyph too large:" -- " xMin = %d, xMax = %d\n", -- cbox.xMin >> 6, cbox.xMax >> 6 )); -- return Smooth_Err_Raster_Overflow; -- } -- else -- width = ( cbox.xMax - cbox.xMin ) >> 6; -+ if (scale_value != 1.0) -+ FT_Outline_Transform( outline, &scaleMat ); - -- if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) -- { -- FT_ERROR(( "ft_smooth_render_generic: glyph too large:" -- " yMin = %d, yMax = %d\n", -- cbox.yMin >> 6, cbox.yMax >> 6 )); -- return Smooth_Err_Raster_Overflow; -+ FT_Outline_Translate( outline, translate_value+0, 0 ); -+ -+ FT_Outline_EmboldenXY( outline, embolden_value, 0 ); - } - else -- height = ( cbox.yMax - cbox.yMin ) >> 6; -- -- bitmap = &slot->bitmap; -- memory = render->root.memory; -- --#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING -- width_org = width; -- height_org = height; -+ { - #endif -+ outline = &slot->outline; -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ /* Need to get this PRIOR to embolden, otherwise bad things happen */ -+ FT_Outline_Get_CBox( outline, &cbox ); -+ -+ /* Various hacks that need to be turned into a new rule set */ -+ /*if ( !autohinted -+ && use_known_settings_on_selected_fonts -+ && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name -+ && ( strcasestr(slot->face->family_name, "Courier New" ) -+ && ( strcasestr(slot->face->style_name, "Regular" ) -+ || strcasestr(slot->face->style_name, "Italic" ) ) ) ) -+ FT_Outline_Embolden( outline, 24 );*/ -+ -+ if (!autohinted -+ && use_known_settings_on_selected_fonts -+ && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name -+ && strcasestr(slot->face->family_name, "Times New Roman" ) -+ && strcasestr(slot->face->style_name, "Italic" ) ) -+ FT_Outline_EmboldenXY( outline, 12, 0 ); -+ -+ if ( use_known_settings_on_selected_fonts -+ && autohinted && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name -+ && strcasestr(slot->face->family_name, "FreeSerif" ) -+ && strcasestr(slot->face->style_name, "Italic" ) ) -+ FT_Outline_EmboldenXY( outline, 8, 0 ); -+ -+ if( global_embolden_x_value != 0 || global_embolden_y_value != 0 ) -+ FT_Outline_EmboldenXY( outline, global_embolden_x_value, global_embolden_y_value ); -+ -+ if( (bold_embolden_x_value != 0 || bold_embolden_y_value != 0) -+ && (slot->face->style_name -+ && ( strcasestr(slot->face->style_name, "Bold") -+ || strcasestr(slot->face->style_name, "Black") ) -+ || ( slot->face->style_flags -+ && slot->face->style_flags & FT_STYLE_FLAG_BOLD ) ) ) -+ FT_Outline_EmboldenXY( outline, bold_embolden_x_value, bold_embolden_y_value ); - -- /* release old bitmap buffer */ -- if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) -- { -- FT_FREE( bitmap->buffer ); -- slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; -+ FT_Outline_Copy(outline, outline_orig); - } - -- /* allocate new one */ -- pitch = width; -- if ( hmul ) -+ /* translate the outline to the new origin if needed */ -+ if (align_called == 0) - { -- width = width * 3; -- pitch = FT_PAD_CEIL( width, 4 ); -- } -+ FT_Pos enlarge_cbox = 0; - -- if ( vmul ) -- height *= 3; -+ /* enlarge for grayscale rendering */ -+ if ( mode == FT_RENDER_MODE_NORMAL ) enlarge_cbox = 64; - -- x_shift = (FT_Int) cbox.xMin; -- y_shift = (FT_Int) cbox.yMin; -- x_left = (FT_Int)( cbox.xMin >> 6 ); -- y_top = (FT_Int)( cbox.yMax >> 6 ); -+ if ( origin ) -+ FT_Outline_Translate( outline, origin->x, origin->y ); - --#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING -+ /* compute the control box, and grid fit it */ -+ /*FT_Outline_Get_CBox( outline, &cbox );*/ -+ -+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin - enlarge_cbox ); -+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); -+ cbox.xMax = FT_PIX_CEIL( cbox.xMax + enlarge_cbox ); -+ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); -+#else -+ if ( origin ) -+ FT_Outline_Translate( outline, origin->x, origin->y ); -+ -+ /* compute the control box, and grid fit it */ -+ FT_Outline_Get_CBox( outline, &cbox ); -+ -+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); -+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); -+ cbox.xMax = FT_PIX_CEIL( cbox.xMax ); -+ cbox.yMax = FT_PIX_CEIL( cbox.yMax ); -+#endif - -- if ( slot->library->lcd_filter_func ) -- { -- FT_Int extra = slot->library->lcd_extra; -+ if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin ) -+ { -+ FT_ERROR(( "ft_smooth_render_generic: glyph too large:" -+ " xMin = %d, xMax = %d\n", -+ cbox.xMin >> 6, cbox.xMax >> 6 )); -+ return Smooth_Err_Raster_Overflow; -+ } -+ else -+ width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); -+ -+ if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin ) -+ { -+ FT_ERROR(( "ft_smooth_render_generic: glyph too large:" -+ " yMin = %d, yMax = %d\n", -+ cbox.yMin >> 6, cbox.yMax >> 6 )); -+ return Smooth_Err_Raster_Overflow; -+ } -+ else -+ height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); - -+ bitmap = &slot->bitmap; -+ memory = render->root.memory; - -+#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING -+ width_org = width; -+ height_org = height; -+#endif -+ -+ /* release old bitmap buffer */ -+ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) -+ { -+ FT_FREE( bitmap->buffer ); -+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; -+ } -+ -+ /* allocate new one */ -+ pitch = width; - if ( hmul ) - { -- x_shift -= 64 * ( extra >> 1 ); -- width += 3 * extra; -- pitch = FT_PAD_CEIL( width, 4 ); -- x_left -= extra >> 1; -+ width = width * 3; -+ pitch = FT_PAD_CEIL( width, 4 ); - } - - if ( vmul ) -+ height *= 3; -+ -+ x_shift = (FT_Int) cbox.xMin; -+ y_shift = (FT_Int) cbox.yMin; -+ x_left = (FT_Int)( cbox.xMin >> 6 ); -+ y_top = (FT_Int)( cbox.yMax >> 6 ); -+ -+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING -+ -+ if ( slot->library->lcd_filter_func ) - { -- y_shift -= 64 * ( extra >> 1 ); -- height += 3 * extra; -- y_top += extra >> 1; -+ FT_Int extra = slot->library->lcd_extra; -+ -+ -+ if ( hmul ) -+ { -+ x_shift -= 64 * ( extra >> 1 ); -+ width += 3 * extra; -+ pitch = FT_PAD_CEIL( width, 4 ); -+ x_left -= extra >> 1; -+ } -+ -+ if ( vmul ) -+ { -+ y_shift -= 64 * ( extra >> 1 ); -+ height += 3 * extra; -+ y_top += extra >> 1; -+ } - } -+#endif -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET - } - - #endif -@@ -239,6 +3475,9 @@ - bitmap->pitch = pitch; - - /* translate outline to render it into the bitmap */ -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if (align_called == 0) -+#endif - FT_Outline_Translate( outline, -x_shift, -y_shift ); - - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) -@@ -288,9 +3527,107 @@ - vec->y /= 3; - } - -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET -+ if ( ppem <= MAX_PPEM && ppem >= MIN_PPEM ) -+ { -+ if ( align_called == 0 && (alignment_strength > 0 || fitting_strength > 0)) -+ _lcd_stem_align ( bitmap, mode, slot, &translate_value, &scale_value, -+ alignment_strength, fitting_strength, &embolden_value ); -+ -+ if ((translate_value != 0 || scale_value != 1.0) && align_called == 0) -+ { -+ align_called = 1; -+ goto RERENDER; -+ } -+ -+ if ( mode == FT_RENDER_MODE_LCD ) -+ { -+ -+ if (fringe_filter_strength > 0 /*&& autohinted*/) -+ _ft_lcd_fringe_filter( bitmap, mode, fringe_filter_strength, slot->library ); -+ -+ /*if (autohinted) -+ _ft_lcd_stem_end_filter( bitmap, mode, 100, slot->library );*/ -+ -+ if ( gamma_correction_lt > 0 && gamma_correction_value != 1.0 ) -+ _ft_lcd_gamma_correction_correction( bitmap, mode, slot, gamma_correction_lt, gamma_correction_value ); -+ -+ chromeos_cutoff = (FT_Byte)(0.5 * 255.0) * (chromeos_style_sharpening_strength / 100.0); -+ chromeos_gamma_value = 1; -+ -+ if (chromeos_style_sharpening_strength > 0) -+ _ft_lcd_chromeos_sharpen( bitmap, mode, chromeos_cutoff, chromeos_gamma_value ); -+ -+ if (ppem > 8) -+ if (windows_style_sharpening_strength > 0) -+ _ft_lcd_windows_sharpen( bitmap, mode, windows_style_sharpening_strength, slot->library ); -+ -+ if (autohinted && (cur_width * 100) / 64 > autohint_horizontal_stem_darken_strength -+ && autohint_horizontal_stem_darken_strength != 0) -+ autohint_horizontal_stem_darken_strength = (cur_width * 100) / 64; -+ -+ if (autohint_horizontal_stem_darken_strength > 100) -+ autohint_horizontal_stem_darken_strength = 100; -+ -+ /* only do on autohinted fonts */ -+ /* Necessary to do on some non-thin fonts, which is why it is outside */ -+ /* of the below conditional */ -+ if (autohint_horizontal_stem_darken_strength > 0 && autohinted ) -+ _ft_lcd_darken_x ( bitmap, mode, autohint_horizontal_stem_darken_strength, slot->library ); -+ -+ /* Enhance thin fonts */ -+ if (autohinted) -+ { -+ /* if forcibly set use that, otherwise make a good estimate */ -+ if ( !_ft_bitmap_bc ( bitmap, (float)get_brightness(slot->face->family_name, ppem) / 300.0, -+ (float)get_contrast(slot->face->family_name, ppem) / 300.0)) -+ { -+ FT_Bool is_fixed_name = FALSE; -+ if ( slot->face->family_name -+ && strcasestr(slot->face->family_name, "Mono") ) -+ is_fixed_name = TRUE; -+ -+ /* Darken vertical stems */ -+ _ft_lcd_darken_y ( bitmap, mode, autohint_vertical_stem_darken_strength, slot->library); -+ -+ /* Adjust brightness and contrast automatically based on stem width */ -+ if (cur_width != 0 && cur_width < 30 ) cur_width = 30; -+ if (cur_width >= 30 && cur_width <= 60 ) -+ { -+ float ppem_factor = sliding_scale ( 5, 11, 0.0, 1.0, ppem); -+ float brightness_factor = sliding_scale ( 30, 52, -.3, 0.0, cur_width); -+ float contrast_factor = sliding_scale ( 30, 52, .45, 0.0, cur_width); -+ _ft_bitmap_bc ( bitmap, ppem_factor * brightness_factor, ppem_factor * contrast_factor); -+ -+ /* Only cap variable width thin-stemmed fonts */ -+ if (!FT_IS_FIXED_WIDTH( slot->face ) && !is_fixed_name) -+ _ft_bitmap_cap ( bitmap, (cur_width * 150) / 64, slot->library ); -+ } -+ } -+ } -+ -+ -+ if ( slot->library->lcd_filter_func ) -+ slot->library->lcd_filter_func( bitmap, mode, slot->library ); -+ -+ if (grayscale_filter_strength > 0) -+ _ft_lcd_grayscale_filter( bitmap, mode, grayscale_filter_strength, slot->library ); -+ -+ } -+ -+ /* Global values */ -+ if (brightness_value != 0 || contrast_value != 0) -+ _ft_bitmap_bc ( bitmap, (float)brightness_value / 300.0, (float)contrast_value / 300.0); -+ -+ FT_Outline_Done( slot->library, outline_orig ); -+ } -+ else if ( mode == FT_RENDER_MODE_LCD && slot->library->lcd_filter_func ) -+ slot->library->lcd_filter_func( bitmap, mode, slot->library ); -+#else - if ( slot->library->lcd_filter_func ) - slot->library->lcd_filter_func( bitmap, mode, slot->library ); - -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */ - #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - /* render outline into bitmap */ diff --git a/media-libs/freetype/freetype-2.4.10-r1.ebuild b/media-libs/freetype/freetype-2.4.10-r1.ebuild deleted file mode 100644 index e0bdde5..0000000 --- a/media-libs/freetype/freetype-2.4.10-r1.ebuild +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright 1999-2012 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -EAPI="4" - -inherit autotools eutils flag-o-matic libtool multilib - -DESCRIPTION="A high-quality and portable font engine" -HOMEPAGE="http://www.freetype.org/" -SRC_URI="mirror://sourceforge/freetype/${P/_/}.tar.bz2 - utils? ( mirror://sourceforge/freetype/ft2demos-${PV}.tar.bz2 ) - doc? ( mirror://sourceforge/freetype/${PN}-doc-${PV}.tar.bz2 )" - -LICENSE="FTL GPL-2" -SLOT="2" -KEYWORDS="~amd64 ~x86" -IUSE="X auto-hinter bindist bzip2 debug doc fontforge lcdfilter static-libs utils" - -DEPEND="sys-libs/zlib - bzip2? ( app-arch/bzip2 ) - X? ( x11-libs/libX11 - x11-libs/libXau - x11-libs/libXdmcp )" - -RDEPEND="${DEPEND} - lcdfilter? ( media-libs/fontconfig-infinality )" - -src_prepare() { - enable_option() { - sed -i -e "/#define $1/a #define $1" \ - include/freetype/config/ftoption.h \ - || die "unable to enable option $1" - } - - disable_option() { - sed -i -e "/#define $1/ { s:^:/*:; s:$:*/: }" \ - include/freetype/config/ftoption.h \ - || die "unable to disable option $1" - } - - if ! use bindist; then - # See http://freetype.org/patents.html - # ClearType is covered by several Microsoft patents in the US - enable_option FT_CONFIG_OPTION_SUBPIXEL_RENDERING - fi - - if use auto-hinter; then - disable_option TT_CONFIG_OPTION_BYTECODE_INTERPRETER - enable_option TT_CONFIG_OPTION_UNPATENTED_HINTING - fi - - if use debug; then - enable_option FT_DEBUG_LEVEL_TRACE - enable_option FT_DEBUG_MEMORY - fi - - disable_option FT_CONFIG_OPTION_OLD_INTERNALS - - if use lcdfilter; then - epatch "${FILESDIR}"/freetype-add-subpixel-hinting-infinality.patch - epatch "${FILESDIR}"/freetype-entire-infinality-patchset.patch - - enable_option FT_CONFIG_OPTION_SUBPIXEL_RENDERING - enable_option TT_CONFIG_OPTION_SUBPIXEL_HINTING - fi - - epatch "${FILESDIR}"/${PN}-2.3.2-enable-valid.patch - - if use utils; then - cd "${WORKDIR}/ft2demos-${PV}" - sed -i -e "s:\.\.\/freetype2$:../freetype-${PV}:" Makefile || die - # Disable tests needing X11 when USE="-X". (bug #177597) - if ! use X; then - sed -i -e "/EXES\ +=\ ftdiff/ s:^:#:" Makefile || die - fi - fi - - if use prefix; then - cd "${S}"/builds/unix - eautoreconf - else - elibtoolize - fi - epunt_cxx -} - -src_configure() { - append-flags -fno-strict-aliasing - type -P gmake &> /dev/null && export GNUMAKE=gmake - - # we need non-/bin/sh to run configure - [[ -n ${CONFIG_SHELL} ]] && \ - sed -i -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" \ - "${S}"/builds/unix/configure - - econf \ - $(use_enable static-libs static) \ - $(use_with bzip2) -} - -src_compile() { - emake - - if use utils; then - einfo "Building utils" - cd "${WORKDIR}/ft2demos-${PV}" - # fix for Prefix, bug #339334 - emake X11_PATH="${EPREFIX}/usr/$(get_libdir)" - fi -} - -src_install() { - emake DESTDIR="${D}" install - - if use utils; then - einfo "Installing utils" - rm "${WORKDIR}"/ft2demos-${PV}/bin/README - for ft2demo in ../ft2demos-${PV}/bin/*; do - ./builds/unix/libtool --mode=install $(type -P install) -m 755 "$ft2demo" \ - "${ED}"/usr/bin - done - fi - - if use fontforge; then - # Probably fontforge needs less but this way makes things simplier... - einfo "Installing internal headers required for fontforge" - find src/truetype include/freetype/internal -name '*.h' | \ - while read header; do - mkdir -p "${ED}/usr/include/freetype2/internal4fontforge/$(dirname ${header})" - cp ${header} "${ED}/usr/include/freetype2/internal4fontforge/$(dirname ${header})" - done - fi - - prune_libtool_files - - dodoc ChangeLog README - dodoc docs/{CHANGES,CUSTOMIZE,DEBUG,*.txt,PROBLEMS,TODO} - - use doc && dohtml -r docs/* - -} |