Gentoo Archives: gentoo-commits

From: Ben de Groot <yngwin@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/betagarden:master commit in: app-admin/eselect-infinality/files/, media-libs/freetype/files/, ...
Date: Sun, 29 Jul 2012 18:08:58
Message-Id: 1343585301.cfb081676340152543cb2d281743f573548bc9f0.yngwin@gentoo
1 commit: cfb081676340152543cb2d281743f573548bc9f0
2 Author: Ben de Groot <yngwin <AT> gmail <DOT> com>
3 AuthorDate: Sun Jul 29 18:08:21 2012 +0000
4 Commit: Ben de Groot <yngwin <AT> gentoo <DOT> org>
5 CommitDate: Sun Jul 29 18:08:21 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/betagarden.git;a=commit;h=cfb08167
7
8 Remove infinality packages, they are in official tree now
9
10 ---
11 .../eselect-infinality-20120618.ebuild | 29 -
12 .../files/infinality.eselect-20120618 | 102 -
13 media-libs/fontconfig-infinality/files/Xresources | 32 -
14 .../files/infinality-settings.sh | 1014 -----
15 .../fontconfig-infinality-20120619.ebuild | 48 -
16 .../files/freetype-2.3.2-enable-valid.patch | 22 -
17 .../files/freetype-2.4.9-type1-incremental.patch | 101 -
18 .../freetype-add-subpixel-hinting-infinality.patch | 2927 -------------
19 ...eetype-enable-subpixel-hinting-infinality.patch | 21 -
20 .../freetype-entire-infinality-patchset.patch | 4630 --------------------
21 media-libs/freetype/freetype-2.4.10-r1.ebuild | 142 -
22 11 files changed, 0 insertions(+), 9068 deletions(-)
23
24 diff --git a/app-admin/eselect-infinality/eselect-infinality-20120618.ebuild b/app-admin/eselect-infinality/eselect-infinality-20120618.ebuild
25 deleted file mode 100644
26 index 54700f1..0000000
27 --- a/app-admin/eselect-infinality/eselect-infinality-20120618.ebuild
28 +++ /dev/null
29 @@ -1,29 +0,0 @@
30 -# Copyright 1999-2012 Gentoo Foundation
31 -# Distributed under the terms of the GNU General Public License v2
32 -# $Header: $
33 -
34 -EAPI=4
35 -
36 -DESCRIPTION="Eselect module to choose an infinality font rendering style"
37 -HOMEPAGE="https://github.com/MeisterP/infinality-overlay"
38 -SRC_URI=""
39 -
40 -LICENSE="GPL-2"
41 -SLOT="0"
42 -KEYWORDS="~amd64 ~x86"
43 -IUSE=""
44 -
45 -RDEPEND="app-admin/eselect"
46 -
47 -src_unpack() {
48 - mkdir "${S}"
49 -}
50 -
51 -src_install() {
52 - insinto "/usr/share/eselect/modules"
53 - newins "${FILESDIR}"/infinality.eselect-"${PV}" infinality.eselect
54 -}
55 -
56 -pkg_postinst() {
57 - elog "Use eselect infinality to select a rendering style"
58 -}
59
60 diff --git a/app-admin/eselect-infinality/files/infinality.eselect-20120618 b/app-admin/eselect-infinality/files/infinality.eselect-20120618
61 deleted file mode 100644
62 index c8fe0a5..0000000
63 --- a/app-admin/eselect-infinality/files/infinality.eselect-20120618
64 +++ /dev/null
65 @@ -1,102 +0,0 @@
66 -# -*-eselect-*- vim: ft=eselect
67 -# Copyright 2005-2012 Gentoo Foundation
68 -# Distributed under the terms of the GNU GPL version 2 or later
69 -
70 -DESCRIPTION="Manage the /etc/fonts/infinality/conf.d symlink"
71 -MAINTAINER="poncho@××××××.ch"
72 -VERSION="20120618"
73 -
74 -# find a list of symlink targets
75 -find_targets() {
76 - local f
77 - for f in "${EROOT}"/etc/fonts/infinality/styles.conf.avail/*; do
78 - [[ -d ${f} ]] && basename "${f}"
79 - done
80 -}
81 -
82 -# remove the symlink
83 -remove_symlink() {
84 - rm "${EROOT}/etc/fonts/infinality/conf.d"
85 -}
86 -
87 -# set the symlink
88 -set_symlink() {
89 - local target=$1
90 -
91 - if is_number "${target}"; then
92 - local targets=( $(find_targets) )
93 - target=${targets[target-1]}
94 - fi
95 -
96 - [[ -z ${target} || ! -d ${EROOT}/etc/fonts/infinality/styles.conf.avail/${target} ]] \
97 - && die -q "Target \"$1\" doesn't appear to be valid!"
98 -
99 - ln -s "styles.conf.avail/${target}" "${EROOT}/etc/fonts/infinality/conf.d"
100 - echo "Selected style: ${target}"
101 - echo "You should update /etc/env.d/99lcdfilter to match your current style"
102 -}
103 -
104 -### show action ###
105 -
106 -describe_show() {
107 - echo "Show the current style symlink"
108 -}
109 -
110 -do_show() {
111 - write_list_start "Current style symlink:"
112 - if [[ -L ${EROOT}/etc/fonts/infinality/conf.d ]]; then
113 - local style=$(canonicalise "${EROOT}/etc/fonts/infinality/conf.d")
114 - write_kv_list_entry "${style}" ""
115 - else
116 - write_kv_list_entry "(unset)" ""
117 - fi
118 -}
119 -
120 -### list action ###
121 -
122 -describe_list() {
123 - echo "List available styles"
124 -}
125 -
126 -do_list() {
127 - local i targets=( $(find_targets) )
128 -
129 - write_list_start "Available styles:"
130 - for (( i = 0; i < ${#targets[@]}; i++ )); do
131 - # highlight the target where the symlink is pointing to
132 - [[ ${targets[i]} = \
133 - $(basename "$(canonicalise "${EROOT}/etc/fonts/infinality/conf.d")") ]] \
134 - && targets[i]=$(highlight_marker "${targets[i]}")
135 - done
136 - write_numbered_list -m "(none found)" "${targets[@]}"
137 -}
138 -
139 -### set action ###
140 -
141 -describe_set() {
142 - echo "Set a new style"
143 -}
144 -
145 -describe_set_parameters() {
146 - echo "<target>"
147 -}
148 -
149 -describe_set_options() {
150 - echo "target : Target name or number (from 'list' action)"
151 -}
152 -
153 -do_set() {
154 - [[ -z $1 ]] && die -q "You didn't tell me what to set the symlink to"
155 - [[ $# -gt 1 ]] && die -q "Too many parameters"
156 -
157 - if [[ -L ${EROOT}/etc/fonts/infinality/conf.d ]]; then
158 - # existing symlink
159 - remove_symlink || die -q "Couldn't remove existing symlink"
160 - set_symlink "$1" || die -q "Couldn't set a new symlink"
161 - elif [[ -e ${EROOT}/etc/fonts/infinality/conf.d ]]; then
162 - # we have something strange
163 - die -q "${EROOT}/etc/fonts/infinality/conf.d exists but is not a symlink"
164 - else
165 - set_symlink "$1" || die -q "Couldn't set a new symlink"
166 - fi
167 -}
168
169 diff --git a/media-libs/fontconfig-infinality/files/Xresources b/media-libs/fontconfig-infinality/files/Xresources
170 deleted file mode 100644
171 index d34e001..0000000
172 --- a/media-libs/fontconfig-infinality/files/Xresources
173 +++ /dev/null
174 @@ -1,32 +0,0 @@
175 -#################################################################
176 -################## EXPLANATION OF SETTINGS ######################
177 -#################################################################
178 -
179 -# XFT settings are like a red-headed stepchild that should be beaten severely.
180 -# These only affect legacy programs, and *parts* of some modern programs like
181 -# google-chrome. We only deal with these settings because we have to, otherwise
182 -# crap will slip by. I recommend using hintslight and autohint as the defaults
183 -# normally in local.conf. The reason hintfull and autohint:0 is needed here
184 -# because otherwise some programs will occassionally request slight hinting for
185 -# a truetype font. When a program does this, Freetype automatically uses the
186 -# autohinter, when you may actually want it to be rendered with the TT hinter,
187 -# (if specified in local.conf). So setting this to hintfull guarantees that the
188 -# TT font will be rendered with the TT hinter (assuming it is specified in
189 -# /etc/fonts/local.conf to be rendered that way.) For TT fonts that you want
190 -# rendered with autohint, specifiying that in the /etc/fonts/local.conf
191 -# should be enough. But you might think that by setting this to hintfull
192 -# that it's going to use Freetype's full autohinting (which we *completely*
193 -# avoid) for fonts you want autohinted. This is where
194 -# INFINALITY_FT_AUTOFIT_FORCE_SLIGHT_HINTING comes in. It tells freetype to
195 -# use slight hinting on fonts set for autohinting, even if the program requests
196 -# full autohinting. Freetype's full hinting only looks OK under certain
197 -# circumstances. The goal of infinality is to make infinality hinting look
198 -# good all the time.
199 -
200 -Xft.antialias: 1
201 -Xft.autohint: 0
202 -Xft.dpi: 96
203 -Xft.hinting: 1
204 -Xft.hintstyle: hintfull
205 -Xft.lcdfilter: lcddefault
206 -Xft.rgba: rgb
207
208 diff --git a/media-libs/fontconfig-infinality/files/infinality-settings.sh b/media-libs/fontconfig-infinality/files/infinality-settings.sh
209 deleted file mode 100644
210 index 6d0a858..0000000
211 --- a/media-libs/fontconfig-infinality/files/infinality-settings.sh
212 +++ /dev/null
213 @@ -1,1014 +0,0 @@
214 -##################################################################
215 -### INFINALITY ENVIRONMENT VARIABLES FOR EXTRA RUN-TIME OPTIONS ##
216 -##################################################################
217 -#
218 -# These environment variables require that their respective patches
219 -# from http://www.infinality.net have been applied to the Freetype
220 -# installation you are using. They will do abolutely
221 -# nothing otherwise!
222 -#
223 -# Of course, the per-user settings will override the system-wide
224 -# settings. Default values indicated below will be used when the
225 -# environment variables below are not defined.
226 -#
227 -# When I say "Default:" below, I'm referring to the default if no
228 -# environment variables are set. Generally this ends up being
229 -# whatever Freetype's default is set to.
230 -#
231 -
232 -
233 -##################################################################
234 -# EXAMPLES
235 -#
236 -# Please see 3/4 down in this file for examples of different settings.
237 -#
238 -
239 -
240 -
241 -
242 -
243 -
244 -#################################################################
245 -################## EXPLANATION OF SETTINGS ######################
246 -#################################################################
247 -
248 -
249 -
250 -##################################################################
251 -# INFINALITY_FT_FILTER_PARAMS
252 -#
253 -# This is a modified version of the patch here:
254 -# http://levelsofdetail.kendeeter.com/2008/12/dynamic_fir_filter_patch.html
255 -#
256 -# Allows you to adjust the FIR filter at runtime instead of at
257 -# compile time. The idea is to have values add up to 100, and be
258 -# symmetrical around the middle value. If the values add up to
259 -# more than 100, the glyphs will appear darker. If less than 100,
260 -# lighter. I recommend using this method to make glyphs darker
261 -# or lighter globally as opposed to using the gamma option (see note in
262 -# the gamma option).
263 -#
264 -# Here are some samples of various filter parameters:
265 -#
266 -# (this has been changed to use integers between 0 and 100 to
267 -# avoid problems with regional differences like comma for decimal point)
268 -#
269 -#
270 -# Strong Extra Smooth "15 20 30 20 15" (extra smooth, natural weight)
271 -# Extra Smooth "20 20 30 20 20" (extra smooth, extra weight)
272 -# Smooth "15 20 32 20 15" (smooth, natural weight)
273 -# Stronger Gibson "11 22 38 22 11" (smooth, extra weight)
274 -# Gibson "11 22 33 22 11" (smooth, natural weight)
275 -# Freetype Light "00 33 34 33 00" (sharp, natural weight) # freetype's "light" LCD filter
276 -# Freetype Default "06 25 44 25 06" (sharp, extra weight) # freetype's default
277 -# Extra Sharp "00 35 35 35 00" (extra sharp, extra weight) # freetype's "light" LCD filter on acid
278 -#
279 -#
280 -# Windows uses something more sharp, maybe along the lines of Freetype's default
281 -#
282 -# Default if no ENV_VARS present: [Freetype's default]
283 -# Recommended: "11 22 38 22 11" (too dark / smooth for some)
284 -#
285 -# Example 1: export INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
286 -#
287 -
288 -INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
289 -
290 -
291 -
292 -##################################################################
293 -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH
294 -#
295 -# This performs analysis on each glyph and determines an amount
296 -# to shift the glyph, left or right, so that it aligns better to
297 -# pixel boundaries.
298 -#
299 -# This results in subtley cleaner looking stems, at the expense of
300 -# proper distances between glyphs. This is only active for sizes
301 -# 10 px or greater and does not apply to bold or italic fonts.
302 -#
303 -# There are also exceptions on a small number of fonts that I've
304 -# not been able to render nicely with alignment enabled. In those
305 -# cases, a forced translation is applied instead.
306 -#
307 -# Possible values:
308 -# 0 through 100 - think of as percentage of strength
309 -#
310 -# 0 corresponds to no shifting whatsoever. In other words, OFF.
311 -#
312 -# 100 corresponds to a full move to a snap zone defined by
313 -# the snapping algorithm, be it left or right. This
314 -# is the full amount any glyph could be moved in order to make it
315 -# align to the pixel.
316 -#
317 -# Values inbetween act as caps. If the algorithm determines that it
318 -# wants to move the glyph .33 of a pixel to the left, but the value
319 -# is set to 50 (i.e. 50%), then the maximum move that would be allowed
320 -# is 50% of half a pixel, in other words .25. So instead of .33 the
321 -# glyph is moved .25 of a pixel.
322 -#
323 -# For a subtle effect that doesn't dramatically affect the glyph, use
324 -# 25 for this and 25 for INFINALITY_FT_STEM_FITTING_STRENGTH
325 -#
326 -# Default if no ENV_VARS present: 0
327 -# Recommended if you want to use it: 100
328 -
329 -INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25
330 -
331 -
332 -
333 -##################################################################
334 -# INFINALITY_FT_STEM_FITTING_STRENGTH
335 -#
336 -# This performs analysis on each glyph and determines an amount
337 -# to horizontally scale the glyph, so that stems align better to
338 -# pixel boundaries. An emboldening (or anti-emboldening) is
339 -# performed afterward to account for stem width exaggeration.
340 -#
341 -# This results in subtley cleaner looking fonts, at the expense of
342 -# proper distances between glyphs and slightly misshapen glyphs.
343 -# This is only active for sizes 10 px or greater and does not
344 -# apply to bold or italic fonts.
345 -#
346 -# There are also exceptions on a small number of fonts that I've
347 -# not been able to render nicely with fitting enabled. In those
348 -# cases, a forced translation is applied instead.
349 -#
350 -#
351 -# Possible values:
352 -# 0 through 100 - think of as percentage of strength
353 -#
354 -# 0 corresponds to no stretching whatsoever. In other words, OFF.
355 -#
356 -# 100 corresponds to a full pixel stretch, be outward or inward. This
357 -# is the full amount any glyph could be stretched in order to make it
358 -# align to a pixel boundary. Which direction is chosen is part
359 -# of the art of what I'm trying to do in the code. ;)
360 -#
361 -#
362 -# Values inbetween act as caps. If the algorithm determines that it
363 -# wants to stretch the glyph .75 of a pixel outward, but the value
364 -# is set to 50 (i.e. 50%), then the maximum move that would be allowed
365 -# is 50% of a pixel, in other words .50. So instead of .75 the
366 -# glyph is stretched .50 of a pixel.
367 -#
368 -# For a subtle effect that doesn't dramatically affect the glyph, use
369 -# 25 for this and 25 for INFINALITY_FT_STEM_FITTING_STRENGTH
370 -#
371 -# Default if no ENV_VARS present: 0
372 -# Recommended if you want to use it: 100
373 -
374 -INFINALITY_FT_STEM_FITTING_STRENGTH=25
375 -
376 -
377 -
378 -##################################################################
379 -# INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE
380 -#
381 -# This allows you to set a ppem at which alignment and fitting
382 -# will reach 100%. As glyphs become larger, more dramatic
383 -# snapping will not affect the glyph shape as much, so it makes
384 -# sense to allow this.
385 -#
386 -# For fonts that are 10 ppem, the values set above for
387 -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH and
388 -# INFINALITY_FT_STEM_FITTING_STRENGTH will be used. As the ppem
389 -# gradually becomes larger, so will the strength settings, and
390 -# they will reach 100% at the ppem you specify here.
391 -#
392 -# This is a simple linear scale.
393 -#
394 -# Possible values:
395 -# 0 means to not use this feature
396 -#
397 -# 11 and up will set the 100% level to that ppem value
398 -#
399 -# Anything else is officially undefined, but I still bound it internally.
400 -#
401 -# Default if no ENV_VARS present: 0
402 -
403 -INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40
404 -
405 -
406 -
407 -##################################################################
408 -# INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS
409 -#
410 -# This applies largely to certain MS fonts, but some others as well.
411 -# it will apply known good settings on a font-by-font basis, regardless
412 -# of the other settings above or below.
413 -#
414 -# - Use known values for selected fonts & ppems that are known to look
415 -# ok with 100:
416 -#
417 -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH
418 -# INFINALITY_FT_STEM_FITTING_STRENGTH
419 -#
420 -# - Use various internal tweaks like compatible widths and other
421 -# font-specific hacks.
422 -# - Use gamma, brightness or contrast adjustments automatically
423 -# on certain fonts. Global settings will still apply afterwards.
424 -# - Enable various forced settings on selective fonts during
425 -# rasterization and stem_alignment.
426 -#
427 -# If set to TRUE, this will use 100 regardless of the values you have
428 -# specified above. It will not affect fonts that are not in this
429 -# small list.
430 -#
431 -# Possible values:
432 -# FALSE means to not use this feature
433 -#
434 -# TRUE will enable this feature
435 -#
436 -# Default if no ENV_VARS present: FALSE
437 -# Recommended: TRUE
438 -#
439 -
440 -INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
441 -
442 -
443 -
444 -##################################################################
445 -# INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH
446 -#
447 -# This enables an algorithm found in ChromeOS for sharpening the
448 -# appearance of glyphs. It is based off this patch:
449 -#
450 -# http://codereview.chromium.org/3298011/diff/9001/media-libs/freetype/files/freetype-2.3.11-lcd-sharpen.patches
451 -#
452 -# It gives glyphs a more "grainy" look through some gamma
453 -# correction. It does tend to thin out vertical stems, which
454 -# may be a feature or a bug depending on your taste ;)
455 -#
456 -#
457 -# Possible values:
458 -# 0 through 100 - think of as percentage of strength
459 -#
460 -# 0 corresponds to no sharpening whatsoever. In other words, OFF.
461 -#
462 -# 25 is good for a subtle effect.
463 -#
464 -# 50 corresponds to the default ChromeOS value.
465 -#
466 -# 100 corresponds to maximum sharpening. This usually results in
467 -# something undesirable looking.
468 -#
469 -#
470 -# As you increase this amount, it is good to decrease the gamma (2nd value)
471 -# of INFINALITY_FT_PSEUDO_GAMMA, and possibly increase
472 -# INFINALITY_FT_STEM_FITTING_STRENGTH and
473 -# INFINALITY_FT_STEM_ALIGNMENT_STRENGTH, as it seems like the algorithm
474 -# lightens stems that aren't fully on-pixel.
475 -#
476 -# Default if no ENV_VARS present: 0
477 -# Recommended: If you're going to use this filter - 50
478 -
479 -INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
480 -
481 -
482 -
483 -##################################################################
484 -# INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH
485 -#
486 -# This enables an algorithm developed with the intention to sharpen
487 -# fonts to look similarly to Windows.
488 -#
489 -# It gives glyphs a more "grainy" look, like the ChromeOS filter
490 -# except it does so more selectively. This prevents the thinning
491 -# of vertical stems that is noticible when a blanket gamma filter
492 -# like the ChromeOS filter is applied.
493 -#
494 -# I also get a "cleaner" impression from the fonts with this Windows
495 -# style filter. This filter was done by 100% experimentation,
496 -# and there things that could probably be improved.
497 -#
498 -# Some may argue that I shouldn't be trying to take the shortcomings
499 -# of the MS approach and bring them here. I disagree, as part
500 -# of freedom is having the right to make your fonts look as
501 -# shitty as you'd like.
502 -#
503 -# Using this filter does somewhat lessen the need to use stem
504 -# fitting and stem alignment, as glyphs appear sharper.
505 -#
506 -# This setting can be used at the same time as the previous chromeOS
507 -# sharpening, and happens after it in the code.
508 -#
509 -#
510 -# Possible values:
511 -# 0 through 100 - think of as percentage of strength
512 -#
513 -# 0 corresponds to no sharpening whatsoever. In other words, OFF.
514 -#
515 -# 10-25 is good for a subtle effect while not completely decimating glyphs.
516 -#
517 -# 50-75 corresponds to probably something in the range that Windows uses.
518 -#
519 -# 100 corresponds to maximum sharpening.
520 -#
521 -#
522 -# Using a high value for this variable along with enabling the
523 -# fringe filter (below) almost eliminates the need
524 -# for INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT to be set to 100,
525 -# and can instead be set at 0. (Setting
526 -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT to 0 prevents missing
527 -# stems in the middle of s. The drawback is that many fonts just look
528 -# way too sharp and grainy at this setting. Your call.)
529 -#
530 -# Default if no ENV_VARS present: 0
531 -# Recommended if you want to use this filter: 65
532 -
533 -INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=10
534 -
535 -
536 -
537 -##################################################################
538 -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT
539 -#
540 -# When using autohinting, horizontal stems you'd find in E, f, T, -,
541 -# etc. are normally not snapped to full integer pixel heights, meaning
542 -# that you will get a semi-dark fringe on these stems, above or
543 -# below the black line of pixels:
544 -#
545 -# ##########
546 -# ##
547 -# ##-------
548 -# #########
549 -# ##
550 -# ##--------
551 -# ##########
552 -#
553 -# (- represents the semi-dark pixels)
554 -#
555 -# Setting this to 100 will force integer pixel heights. Setting it to
556 -# zero will do what Freetype does by default. Anything inbetween will
557 -# act as a weighted average of the two.
558 -#
559 -# This is disabled when the standard width is found (via voodoo) to be
560 -# less than 1 pixel, in order to prevent the vanishing stem issues on
561 -# letters with diagonal stems like a and s.
562 -#
563 -# Under most circumstances, this should be set at 100. If you choose to
564 -# not set it to 100, you may want to set INFINALITY_FT_FRINGE_FILTER_STRENGTH
565 -# to a non-zero value in order to reduce fringing.
566 -#
567 -#
568 -# Possible values:
569 -# 0 - default Freetype value
570 -# 100 - a full pixel
571 -#
572 -#
573 -# Default if no ENV_VARS present: 0
574 -# Recommended: 100
575 -
576 -INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
577 -
578 -
579 -
580 -##################################################################
581 -# INFINALITY_FT_USE_VARIOUS_TWEAKS
582 -#
583 -# - Force autohint when no TT instructions present.
584 -# - Artificially embolden horizontally only.
585 -# - When artificially emboldening, maintain the glyph width.
586 -# - Embolden light and thin-stemmed glyphs automatically.
587 -# - Don't sharpen italics.
588 -#
589 -# Some fonts look bad when stem aligned at certain ppems, no matter
590 -# what. I've put exceptions in to deal with these, included in
591 -# these tweaks. Georgia and Lucida Grande are examples.
592 -#
593 -#
594 -# Possible values:
595 -# true - enable tweaks
596 -# false - do not enable tweaks (do Freetype default)
597 -#
598 -#
599 -# Default if no ENV_VARS present: false
600 -# Recommended: true
601 -
602 -INFINALITY_FT_USE_VARIOUS_TWEAKS=true
603 -
604 -
605 -
606 -##################################################################
607 -# INFINALITY_FT_GAMMA_CORRECTION
608 -#
609 -# This does a weighted gamma correction at the LCD filter phase
610 -# PRIOR to the LCD filter. Unfortunately it does not however
611 -# take into account the color on which the glyph is being rendered
612 -# (or for that matter the color of the glyph),
613 -# which would need to happen in X rendering. It is actually
614 -# using the gamma function in calculations though.
615 -#
616 -# The first value indicates a px value, the second indicates a
617 -# "gamma" value. All sizes less than the px value will be corrected
618 -# on a weighted scale based on the second value.
619 -#
620 -# The gamma value is commonly between 0.0 and 3.0. Due to localization
621 -# issues, the gamma value should be specified as it's actual value
622 -# multiplied by 100. So a gamma of 1.3 would be 130. In practice,
623 -# I'd stay between 40 and 250.
624 -#
625 -#
626 -# Values 1 through 100 will darken the glyph
627 -# Values greater than 100 will lighten the glyph
628 -#
629 -#
630 -# Example 1: Darken glyphs that are less than 10 px. With some fonts
631 -# even 5 or 6px is readable!
632 -# export INFINALITY_FT_GAMMA_CORRECTION="10 60"
633 -#
634 -# Example 2: Lighten all glyphs (below 100px)
635 -# export INFINALITY_FT_GAMMA_CORRECTION="100 150"
636 -#
637 -# Example 3: Do nothing
638 -# export INFINALITY_FT_GAMMA_CORRECTION="0 100"
639 -#
640 -# Default: [No gamma correction]
641 -
642 -INFINALITY_FT_GAMMA_CORRECTION="0 100"
643 -
644 -
645 -
646 -##################################################################
647 -# INFINALITY_FT_BRIGHTNESS
648 -#
649 -# This filter adjusts brightness, using the standard algorithm
650 -# for brightness. It is applied AFTER the LCD filtering.
651 -#
652 -# For a Windows XP look, set brightness to something and contrast to 50
653 -# This will also tend to increase its sharpness.
654 -# These values are relative and don't really mean anything
655 -# however they are satisfactory for a range of appearances.
656 -# Another tip is to use a gamma setting of "1000 110" or something
657 -# over 100 to lighten things before processing.
658 -#
659 -# Default if no ENV_VARS present: 0
660 -# Dark XP Experience: -25
661 -# Light XP Experience: 40
662 -#
663 -# Example: export INFINALITY_FT_BRIGHTNESS="-20"
664 -
665 -INFINALITY_FT_BRIGHTNESS="0"
666 -
667 -
668 -
669 -##################################################################
670 -# INFINALITY_FT_CONTRAST
671 -#
672 -# This filter adjusts contrast, using the standard algorithm
673 -# for contrast. It is applied AFTER the LCD filtering.
674 -#
675 -# For a Windows XP look, set brightness to -25 and contrast to 50
676 -# This will also tend to increase its sharpness.
677 -# These values are relative and don't really mean anything
678 -# however they are satisfactory for a range of appearances.
679 -# Another tip is to use a gamma setting of "1000 110" or something
680 -# over 100 to lighten things before processing.
681 -#
682 -# Default if no ENV_VARS present: 0
683 -# Dark or Light XP Experience: 50
684 -#
685 -# Example: export INFINALITY_FT_CONTRAST="50"
686 -
687 -INFINALITY_FT_CONTRAST="0"
688 -
689 -
690 -
691 -##################################################################
692 -# INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH
693 -#
694 -# This filter adjusts subpixel-rendered glyphs toward grayscale.
695 -# Sometimes this is useful in getting a rendering more like
696 -# OSX.
697 -#
698 -# Range: Integers 0 through 100
699 -# 0 represents no filtering
700 -# 50 represents halfway between subpixel and grayscale
701 -# 100 represents completely grayscale
702 -#
703 -# Default if no ENV_VARS present: 0
704 -# Recommended, if you want to use it: 30
705 -#
706 -# Example: export INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH="33"
707 -
708 -INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH="0"
709 -
710 -
711 -
712 -##################################################################
713 -# INFINALITY_FT_FRINGE_FILTER_STRENGTH
714 -#
715 -# This filter tries to remove the horizontal fringing that is found on
716 -# default autohinted glyphs (similar to OSX-rendered glyphs).
717 -# For example, an E may be rendered so that the middle horizontal
718 -# stem is 100% black, but also has a horizonal row of pixels above
719 -# it that is at 50% intensity. This makes the glyph look dirty,
720 -# however it is technically accurate.
721 -#
722 -# This would be useful in cases where you have
723 -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT set to something less than 100
724 -# but also can affect glyphs at 100, to some degree.
725 -#
726 -# Unless fonts are showing fringes in a way that annoys you, I recommend
727 -# keeping it disabled, as it can slightly interfere with smooth appearance
728 -# sometimes.
729 -#
730 -#
731 -# Range: Integers 0 through 100
732 -# 0 represents no filtering
733 -# 50 represents a 50% reduction of detected fringes
734 -# 100 represents completely removing detected fringes
735 -#
736 -#
737 -# Default if no ENV_VARS present: 0
738 -# Recommended, if you want to use it: 100
739 -#
740 -# Example: export INFINALITY_FT_FRINGE_FILTER_STRENGTH="100"
741 -
742 -INFINALITY_FT_FRINGE_FILTER_STRENGTH="0"
743 -
744 -
745 -
746 -##################################################################
747 -# INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH
748 -#
749 -# This post-filter darkens horizontal stems that autohint renders as semi-dark.
750 -# Freetype will by default not force stems to render to pixel boundaries
751 -# because it results in "vanishing stems". This happens on things like
752 -# s S a and other glyphs with center diagonal stems.
753 -#
754 -# If you have INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT set to 100,
755 -# you're telling it to force pixel boundaries, which can result in the
756 -# vanishing stems. To get around this problem, I internally override the
757 -# INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT setting if the stem width
758 -# is less than a full pixel, regardless. This causes semi-dark stems, but
759 -# at least there are stems there.
760 -#
761 -# This filter is intended to darken those semi-dark stems. I highly
762 -# recommend using this, but setting to a low value like 10, because
763 -# it is particularly sensitive right now, and can make thin fonts
764 -# look weird otherwise.
765 -#
766 -#
767 -# Range: Integers 0 through 100
768 -# 0 represents no darkening
769 -# 50 represents a 50% increase toward 1 pixel in height
770 -# 100 represents a full pixel of height
771 -#
772 -#
773 -# Default if no ENV_VARS present: 0
774 -# Recommended, if you want to use it: 10
775 -#
776 -# Example: export INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH="10"
777 -
778 -INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH="10"
779 -
780 -
781 -
782 -##################################################################
783 -# INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH
784 -#
785 -# This post-filter darkens vertical stems less than 1 pixel that autohint
786 -# renders as semi-dark. This applies mostly to thin fonts like
787 -# Courier New, Raleway, and fonts with the word "Light" in the title or
788 -# style. Although what autohint is doing is technically correct, it
789 -# results in a bad looking rendering because it's too light, at small
790 -# ppems. This filter tries to correct that.
791 -#
792 -# There is an aspect of this that is automatic, so it's safer to use
793 -# larger values for this than the above horizontal ENV_VAR. However
794 -# setting this higher has more impact on thinner fonts. So, I still
795 -# recommend lower values.
796 -#
797 -#
798 -# Range: Integers 0 through 100
799 -# 0 represents no darkening
800 -# 50 represents a 50% increase (from current strength) toward 1 pixel
801 -# 100 represents a full pixel of width
802 -#
803 -#
804 -# Default if no ENV_VARS present: 0
805 -# Recommended, if you want to use it: 25
806 -#
807 -# Example: export INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH="25"
808 -
809 -INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH="25"
810 -
811 -
812 -
813 -##################################################################
814 -# INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS
815 -#
816 -# This will slightly stretch some glyphs vertically between 9px
817 -# and 14px (inclusive). Some people may find this more
818 -# aesthetically pleasing. This only applies to fonts that are
819 -# using autohint. I used to recommend this to be set true, but
820 -# it does mess with some (less popular) glyphs in a nasty way.
821 -#
822 -# The goal here is to increase the height of some fonts by 1 px
823 -# but leave the x-height where it is. Arial is a good example
824 -# of this working properly. Compare the heights of Arial, Times
825 -# and Freesans with this on, vs. TT hinted versions of Arial and
826 -# Times.
827 -#
828 -#
829 -# Possible values:
830 -# true - enable height adjustment
831 -# false - do not enable height adjustment
832 -#
833 -#
834 -# Default: false
835 -
836 -INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
837 -
838 -
839 -# Experimental emboldening values for OSX mode
840 -INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE=0
841 -INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE=0
842 -INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE=0
843 -INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE=0
844 -
845 -#################################################################
846 -########################### EXAMPLES ############################
847 -#################################################################
848 -#
849 -# Make sure to set your style in /etc/fonts/local.conf too.
850 -#
851 -# Possible options:
852 -#
853 -# DEFAULT - Use above settings. A compromise that should please most people.
854 -# OSX - Simulate OSX rendering
855 -# UBUNTU - Simulate UBUNTU rendering
856 -# LINUX - Generic "Linux" style - no snapping or certain other tweaks
857 -# WINDOWS - Simulate Windows rendering
858 -# WINDOWS7 - Simulate Windows rendering with normal glyphs
859 -# WINDOWS7LIGHT- Simulate Windows 7 rendering with lighter glyphs
860 -# WINDOWS - Simulate Windows rendering
861 -# VANILLA - Just subpixel hinting
862 -# CUSTOM - Your own choice. See below
863 -# ----- Infinality styles -----
864 -# CLASSIC - Infinality rendering circa 2010. No snapping.
865 -# NUDGE - CLASSIC with lightly stem snapping and tweaks
866 -# PUSH - CLASSIC with medium stem snapping and tweaks
867 -# SHOVE - Full stem snapping and tweaks without sharpening
868 -# SHARPENED - Full stem snapping, tweaks, and Windows-style sharpening
869 -# INFINALITY - Settings I use
870 -# DISABLED - Act as though running without the extra infinality enhancements (just subpixel hinting).
871 -
872 -### NEEDS WORK ###
873 -################# OSX STYLE #################
874 -
875 -#INFINALITY_FT_FILTER_PARAMS="03 32 38 32 03"
876 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=25
877 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
878 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
879 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
880 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
881 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
882 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
883 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
884 -#INFINALITY_FT_GAMMA_CORRECTION="1000 80"
885 -#INFINALITY_FT_BRIGHTNESS="10"
886 -#INFINALITY_FT_CONTRAST="20"
887 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false
888 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
889 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0
890 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
891 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
892 -#INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE=0
893 -#INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE=8
894 -#INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE=16
895 -#INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE=0
896 -
897 -
898 -
899 -
900 -################# UBUNTU STYLE #################
901 -
902 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
903 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
904 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
905 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
906 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
907 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
908 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
909 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
910 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
911 -#INFINALITY_FT_GAMMA_CORRECTION="1000 80"
912 -#INFINALITY_FT_BRIGHTNESS="-10"
913 -#INFINALITY_FT_CONTRAST="15"
914 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
915 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
916 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0
917 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
918 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
919 -
920 -
921 -
922 -
923 -################# LINUX STYLE #################
924 -
925 -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06"
926 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
927 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
928 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
929 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
930 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
931 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
932 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
933 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
934 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
935 -#INFINALITY_FT_BRIGHTNESS="0"
936 -#INFINALITY_FT_CONTRAST="0"
937 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
938 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
939 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
940 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
941 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
942 -
943 -
944 -
945 -################# WINDOWS XP STYLE LIGHT #################
946 -
947 -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06"
948 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
949 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100
950 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
951 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
952 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65
953 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
954 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=15
955 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15
956 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120"
957 -#INFINALITY_FT_BRIGHTNESS="20"
958 -#INFINALITY_FT_CONTRAST="30"
959 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
960 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
961 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
962 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30
963 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
964 -
965 -
966 -
967 -################# WINDOWS 7 STYLE LIGHT #################
968 -
969 -#INFINALITY_FT_FILTER_PARAMS="20 25 38 25 05"
970 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
971 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100
972 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
973 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
974 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=100
975 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
976 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
977 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
978 -#INFINALITY_FT_GAMMA_CORRECTION="1000 160"
979 -#INFINALITY_FT_BRIGHTNESS="0"
980 -#INFINALITY_FT_CONTRAST="20"
981 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
982 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
983 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
984 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30
985 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
986 -
987 -
988 -
989 -################# WINDOWS XP STYLE #################
990 -
991 -#INFINALITY_FT_FILTER_PARAMS="06 25 44 25 06"
992 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
993 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100
994 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
995 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
996 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65
997 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
998 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=15
999 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15
1000 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120"
1001 -#INFINALITY_FT_BRIGHTNESS="10"
1002 -#INFINALITY_FT_CONTRAST="20"
1003 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1004 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
1005 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1006 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30
1007 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1008 -
1009 -
1010 -
1011 -################# WINDOWS 7 STYLE #################
1012 -
1013 -#INFINALITY_FT_FILTER_PARAMS="20 25 42 25 06"
1014 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1015 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=100
1016 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1017 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1018 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65
1019 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1020 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
1021 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
1022 -#INFINALITY_FT_GAMMA_CORRECTION="1000 120"
1023 -#INFINALITY_FT_BRIGHTNESS="10"
1024 -#INFINALITY_FT_CONTRAST="20"
1025 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1026 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
1027 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1028 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
1029 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1030 -
1031 -
1032 -
1033 -############### VANILLA STYLE ##############
1034 -
1035 -#INFINALITY_FT_FILTER_PARAMS="06 25 38 25 06"
1036 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1037 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1038 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0
1039 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0
1040 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1041 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1042 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
1043 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
1044 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1045 -#INFINALITY_FT_BRIGHTNESS="0"
1046 -#INFINALITY_FT_CONTRAST="0"
1047 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false
1048 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
1049 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=0
1050 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
1051 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
1052 -
1053 -
1054 -
1055 -############### CLASSIC INFINALITY STYLE ##############
1056 -
1057 -#INFINALITY_FT_FILTER_PARAMS="06 25 38 25 06"
1058 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1059 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1060 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=0
1061 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=0
1062 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1063 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1064 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=0
1065 -#INFINALITY_FT_STEM_FITTING_STRENGTH=0
1066 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1067 -#INFINALITY_FT_BRIGHTNESS="0"
1068 -#INFINALITY_FT_CONTRAST="0"
1069 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1070 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1071 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1072 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
1073 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
1074 -
1075 -
1076 -
1077 -################# NUDGE STYLE #################
1078 -
1079 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1080 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1081 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1082 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1083 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1084 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1085 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1086 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25
1087 -#INFINALITY_FT_STEM_FITTING_STRENGTH=15
1088 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1089 -#INFINALITY_FT_BRIGHTNESS="0"
1090 -#INFINALITY_FT_CONTRAST="0"
1091 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1092 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1093 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1094 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30
1095 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
1096 -
1097 -
1098 -
1099 -################# PUSH STYLE #################
1100 -
1101 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1102 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1103 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1104 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1105 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1106 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1107 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1108 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=75
1109 -#INFINALITY_FT_STEM_FITTING_STRENGTH=50
1110 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1111 -#INFINALITY_FT_BRIGHTNESS="0"
1112 -#INFINALITY_FT_CONTRAST="0"
1113 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1114 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1115 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1116 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=30
1117 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1118 -
1119 -
1120 -
1121 -################# INFINALITY STYLE #################
1122 -
1123 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1124 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1125 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1126 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1127 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1128 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=5
1129 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1130 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25
1131 -#INFINALITY_FT_STEM_FITTING_STRENGTH=25
1132 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1133 -#INFINALITY_FT_BRIGHTNESS="0"
1134 -#INFINALITY_FT_CONTRAST="0"
1135 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1136 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1137 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1138 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40
1139 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1140 -
1141 -
1142 -
1143 -################# SHOVE STYLE #################
1144 -
1145 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1146 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1147 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1148 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1149 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1150 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1151 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1152 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=100
1153 -#INFINALITY_FT_STEM_FITTING_STRENGTH=100
1154 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1155 -#INFINALITY_FT_BRIGHTNESS="0"
1156 -#INFINALITY_FT_CONTRAST="0"
1157 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1158 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1159 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1160 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
1161 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1162 -
1163 -
1164 -
1165 -################# SHARPENED INFINALITY STYLE #################
1166 -
1167 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1168 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1169 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1170 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1171 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1172 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=65
1173 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1174 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=25
1175 -#INFINALITY_FT_STEM_FITTING_STRENGTH=25
1176 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1177 -#INFINALITY_FT_BRIGHTNESS="0"
1178 -#INFINALITY_FT_CONTRAST="0"
1179 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1180 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1181 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1182 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=40
1183 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1184 -
1185 -
1186 -
1187 -################# DISABLED STYLE #################
1188 -
1189 -#INFINALITY_FT_FILTER_PARAMS=
1190 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=
1191 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=
1192 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=
1193 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=
1194 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=
1195 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=
1196 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=
1197 -#INFINALITY_FT_STEM_FITTING_STRENGTH=
1198 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1199 -#INFINALITY_FT_BRIGHTNESS="0"
1200 -#INFINALITY_FT_CONTRAST="0"
1201 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=false
1202 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=false
1203 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=
1204 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=
1205 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=false
1206 -
1207 -
1208 -
1209 -################# CUSTOM STYLE #################
1210 -
1211 -#INFINALITY_FT_FILTER_PARAMS="11 22 38 22 11"
1212 -#INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH=0
1213 -#INFINALITY_FT_FRINGE_FILTER_STRENGTH=0
1214 -#INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH=10
1215 -#INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH=25
1216 -#INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH=0
1217 -#INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH=0
1218 -#INFINALITY_FT_STEM_ALIGNMENT_STRENGTH=100
1219 -#INFINALITY_FT_STEM_FITTING_STRENGTH=100
1220 -#INFINALITY_FT_GAMMA_CORRECTION="0 100"
1221 -#INFINALITY_FT_BRIGHTNESS="0"
1222 -#INFINALITY_FT_CONTRAST="0"
1223 -#INFINALITY_FT_USE_VARIOUS_TWEAKS=true
1224 -#INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS=true
1225 -#INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT=100
1226 -#INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE=0
1227 -#INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS=true
1228 \ No newline at end of file
1229
1230 diff --git a/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild b/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild
1231 deleted file mode 100644
1232 index 8d4d6e4..0000000
1233 --- a/media-libs/fontconfig-infinality/fontconfig-infinality-20120619.ebuild
1234 +++ /dev/null
1235 @@ -1,48 +0,0 @@
1236 -# Copyright 1999-2012 Gentoo Foundation
1237 -# Distributed under the terms of the GNU General Public License v2
1238 -# $Header: $
1239 -
1240 -EAPI="4"
1241 -
1242 -DESCRIPTION="Configuration to be used in conjunction with the freetype-infinality subpixel hinting"
1243 -HOMEPAGE="http://www.infinality.net/blog/infinality-freetype-patches/"
1244 -SRC_URI="http://dev.gentoo.org/~yngwin/distfiles/${P}.tar.xz"
1245 -
1246 -LICENSE="MIT"
1247 -SLOT="0"
1248 -KEYWORDS="~amd64 ~x86"
1249 -IUSE=""
1250 -
1251 -DEPEND=""
1252 -RDEPEND="app-admin/eselect-fontconfig
1253 - app-admin/eselect-infinality
1254 - media-libs/freetype:2[lcdfilter]
1255 - >=x11-libs/libXft-2.3.0"
1256 -
1257 -src_configure() {
1258 - :
1259 -}
1260 -
1261 -src_compile() {
1262 - :
1263 -}
1264 -
1265 -src_install() {
1266 - dodoc infinality/{CHANGELOG,CHANGELOG.pre_git,README}
1267 -
1268 - insinto /etc/fonts/conf.avail
1269 - doins conf.avail/52-infinality.conf
1270 -
1271 - insinto /etc/fonts/infinality
1272 - doins -r infinality/{conf.src,styles.conf.avail,infinality.conf}
1273 -
1274 - insinto /etc/X11/
1275 - doins "${FILESDIR}"/Xresources
1276 -
1277 - newenvd "${FILESDIR}"/infinality-settings.sh 99lcdfilter
1278 -}
1279 -
1280 -pkg_postinst() {
1281 - elog "Use eselect fontconfig enable 52-infinality.conf"
1282 - elog "to enable the configuration"
1283 -}
1284
1285 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
1286 deleted file mode 100644
1287 index 44f3bf6..0000000
1288 --- a/media-libs/freetype/files/freetype-2.3.2-enable-valid.patch
1289 +++ /dev/null
1290 @@ -1,22 +0,0 @@
1291 -Enables gxvalid and otvalid modules for use with ftvalid.
1292 -
1293 ---- freetype-2.2.1/modules.cfg.orig 2006-07-07 21:01:09.000000000 -0400
1294 -+++ freetype-2.2.1/modules.cfg 2006-07-07 21:01:54.000000000 -0400
1295 -@@ -110,7 +110,7 @@
1296 - AUX_MODULES += cache
1297 -
1298 - # TrueType GX/AAT table validation. Needs ftgxval.c below.
1299 --# AUX_MODULES += gxvalid
1300 -+AUX_MODULES += gxvalid
1301 -
1302 - # Support for streams compressed with gzip (files with suffix .gz).
1303 - #
1304 -@@ -124,7 +124,7 @@
1305 -
1306 - # OpenType table validation. Needs ftotval.c below.
1307 - #
1308 --# AUX_MODULES += otvalid
1309 -+AUX_MODULES += otvalid
1310 -
1311 - # Auxiliary PostScript driver component to share common code.
1312 - #
1313
1314 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
1315 deleted file mode 100644
1316 index a08c44d..0000000
1317 --- a/media-libs/freetype/files/freetype-2.4.9-type1-incremental.patch
1318 +++ /dev/null
1319 @@ -1,101 +0,0 @@
1320 ---- a/src/type1/t1load.c
1321 -+++ b/src/type1/t1load.c
1322 -@@ -71,6 +71,13 @@
1323 - #include "t1errors.h"
1324 -
1325 -
1326 -+#ifdef FT_CONFIG_OPTION_INCREMENTAL
1327 -+#define IS_INCREMENTAL ( face->root.internal->incremental_interface != 0 )
1328 -+#else
1329 -+#define IS_INCREMENTAL 0
1330 -+#endif
1331 -+
1332 -+
1333 - /*************************************************************************/
1334 - /* */
1335 - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
1336 -@@ -1030,7 +1037,8 @@
1337 - static int
1338 - read_binary_data( T1_Parser parser,
1339 - FT_Long* size,
1340 -- FT_Byte** base )
1341 -+ FT_Byte** base,
1342 -+ FT_Bool incremental )
1343 - {
1344 - FT_Byte* cur;
1345 - FT_Byte* limit = parser->root.limit;
1346 -@@ -1065,8 +1073,12 @@
1347 - }
1348 - }
1349 -
1350 -- FT_ERROR(( "read_binary_data: invalid size field\n" ));
1351 -- parser->root.error = T1_Err_Invalid_File_Format;
1352 -+ if( !incremental )
1353 -+ {
1354 -+ FT_ERROR(( "read_binary_data: invalid size field\n" ));
1355 -+ parser->root.error = T1_Err_Invalid_File_Format;
1356 -+ }
1357 -+
1358 - return 0;
1359 - }
1360 -
1361 -@@ -1387,16 +1399,17 @@
1362 - FT_Byte* base;
1363 -
1364 -
1365 -- /* If the next token isn't `dup' we are done. */
1366 -- if ( parser->root.cursor + 4 < parser->root.limit &&
1367 -- ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
1368 -+ /* If we are out of data, or if the next token isn't `dup', */
1369 -+ /* we are done. */
1370 -+ if ( parser->root.cursor + 4 >= parser->root.limit ||
1371 -+ ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
1372 - break;
1373 -
1374 - T1_Skip_PS_Token( parser ); /* `dup' */
1375 -
1376 - idx = T1_ToInt( parser );
1377 -
1378 -- if ( !read_binary_data( parser, &size, &base ) )
1379 -+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) )
1380 - return;
1381 -
1382 - /* The binary string is followed by one token, e.g. `NP' */
1383 -@@ -1582,7 +1595,7 @@
1384 - cur++; /* skip `/' */
1385 - len = parser->root.cursor - cur;
1386 -
1387 -- if ( !read_binary_data( parser, &size, &base ) )
1388 -+ if ( !read_binary_data( parser, &size, &base, IS_INCREMENTAL ) )
1389 - return;
1390 -
1391 - /* for some non-standard fonts like `Optima' which provides */
1392 -@@ -1871,7 +1884,7 @@
1393 -
1394 -
1395 - parser->root.cursor = start_binary;
1396 -- if ( !read_binary_data( parser, &s, &b ) )
1397 -+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
1398 - return T1_Err_Invalid_File_Format;
1399 - have_integer = 0;
1400 - }
1401 -@@ -1884,7 +1897,7 @@
1402 -
1403 -
1404 - parser->root.cursor = start_binary;
1405 -- if ( !read_binary_data( parser, &s, &b ) )
1406 -+ if ( !read_binary_data( parser, &s, &b, IS_INCREMENTAL ) )
1407 - return T1_Err_Invalid_File_Format;
1408 - have_integer = 0;
1409 - }
1410 -@@ -2160,9 +2173,7 @@
1411 - type1->subrs_len = loader.subrs.lengths;
1412 - }
1413 -
1414 --#ifdef FT_CONFIG_OPTION_INCREMENTAL
1415 -- if ( !face->root.internal->incremental_interface )
1416 --#endif
1417 -+ if ( !IS_INCREMENTAL )
1418 - if ( !loader.charstrings.init )
1419 - {
1420 - FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face\n" ));
1421
1422 diff --git a/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch b/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch
1423 deleted file mode 100644
1424 index 8bb026b..0000000
1425 --- a/media-libs/freetype/files/freetype-add-subpixel-hinting-infinality.patch
1426 +++ /dev/null
1427 @@ -1,2927 +0,0 @@
1428 -diff -Nur freetype-orig/devel/ftoption.h freetype-subpixel/devel/ftoption.h
1429 ---- freetype-orig/devel/ftoption.h 2012-06-14 00:35:57.000000000 -0500
1430 -+++ freetype-subpixel/devel/ftoption.h 2012-06-15 07:31:12.119986648 -0500
1431 -@@ -560,6 +560,28 @@
1432 -
1433 - /*************************************************************************/
1434 - /* */
1435 -+ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */
1436 -+ /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */
1437 -+ /* replaces the native TrueType hinting mechanism when anything but */
1438 -+ /* FT_RENDER_MODE_MONO is requested. */
1439 -+ /* */
1440 -+ /* Enabling this causes the TrueType driver to ignore instructions under */
1441 -+ /* certain conditions. This is done in accordance with the guide here, */
1442 -+ /* with some minor differences: */
1443 -+ /* */
1444 -+ /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
1445 -+ /* */
1446 -+ /* By undefining this, you only compile the code necessary to hint */
1447 -+ /* TrueType glyphs with native TT hinting. */
1448 -+ /* */
1449 -+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
1450 -+ /* defined. */
1451 -+ /* */
1452 -+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1453 -+
1454 -+
1455 -+ /*************************************************************************/
1456 -+ /* */
1457 - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
1458 - /* of the TrueType bytecode interpreter is used that doesn't implement */
1459 - /* any of the patented opcodes and algorithms. The patents related to */
1460 -diff -Nur freetype-orig/include/freetype/config/ftoption.h freetype-subpixel/include/freetype/config/ftoption.h
1461 ---- freetype-orig/include/freetype/config/ftoption.h 2012-06-14 00:35:58.000000000 -0500
1462 -+++ freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500
1463 -@@ -560,6 +560,28 @@
1464 -
1465 - /*************************************************************************/
1466 - /* */
1467 -+ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */
1468 -+ /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */
1469 -+ /* replaces the native TrueType hinting mechanism when anything but */
1470 -+ /* FT_RENDER_MODE_MONO is requested. */
1471 -+ /* */
1472 -+ /* Enabling this causes the TrueType driver to ignore instructions under */
1473 -+ /* certain conditions. This is done in accordance with the guide here, */
1474 -+ /* with some minor differences: */
1475 -+ /* */
1476 -+ /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
1477 -+ /* */
1478 -+ /* By undefining this, you only compile the code necessary to hint */
1479 -+ /* TrueType glyphs with native TT hinting. */
1480 -+ /* */
1481 -+ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
1482 -+ /* defined. */
1483 -+ /* */
1484 -+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1485 -+
1486 -+
1487 -+ /*************************************************************************/
1488 -+ /* */
1489 - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
1490 - /* of the TrueType bytecode interpreter is used that doesn't implement */
1491 - /* any of the patented opcodes and algorithms. The patents related to */
1492 -diff -Nur freetype-orig/include/freetype/internal/ftobjs.h freetype-subpixel/include/freetype/internal/ftobjs.h
1493 ---- freetype-orig/include/freetype/internal/ftobjs.h 2012-06-14 00:35:58.000000000 -0500
1494 -+++ freetype-subpixel/include/freetype/internal/ftobjs.h 2012-06-15 07:31:12.147985698 -0500
1495 -@@ -81,6 +81,14 @@
1496 - #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 )
1497 - #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 )
1498 -
1499 -+ /*
1500 -+ * These are used in ttinterp.c for subpixel hinting with an
1501 -+ * adjustable grids-per-pixel value.
1502 -+ */
1503 -+#define FT_PIX_FLOOR_GRID( x, n ) ( (x) & ~( 64 / (n) - 1 ) )
1504 -+#define FT_PIX_ROUND_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 32 / (n), (n) )
1505 -+#define FT_PIX_CEIL_GRID( x, n ) FT_PIX_FLOOR_GRID( (x) + 63 / (n), (n) )
1506 -+
1507 -
1508 - /*
1509 - * Return the highest power of 2 that is <= value; this correspond to
1510 -diff -Nur freetype-orig/src/truetype/rules.mk freetype-subpixel/src/truetype/rules.mk
1511 ---- freetype-orig/src/truetype/rules.mk 2011-01-03 00:06:51.000000000 -0600
1512 -+++ freetype-subpixel/src/truetype/rules.mk 2012-06-15 07:31:12.148985665 -0500
1513 -@@ -31,7 +31,8 @@
1514 - $(TT_DIR)/ttinterp.c \
1515 - $(TT_DIR)/ttobjs.c \
1516 - $(TT_DIR)/ttpic.c \
1517 -- $(TT_DIR)/ttpload.c
1518 -+ $(TT_DIR)/ttpload.c \
1519 -+ $(TT_DIR)/ttsubpix.c
1520 -
1521 - # TrueType driver headers
1522 - #
1523 -diff -Nur freetype-orig/src/truetype/truetype.c freetype-subpixel/src/truetype/truetype.c
1524 ---- freetype-orig/src/truetype/truetype.c 2009-07-03 08:28:24.000000000 -0500
1525 -+++ freetype-subpixel/src/truetype/truetype.c 2012-06-15 07:31:12.149985631 -0500
1526 -@@ -27,6 +27,7 @@
1527 -
1528 - #ifdef TT_USE_BYTECODE_INTERPRETER
1529 - #include "ttinterp.c"
1530 -+#include "ttsubpix.c"
1531 - #endif
1532 -
1533 - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1534 -diff -Nur freetype-orig/src/truetype/ttgload.c freetype-subpixel/src/truetype/ttgload.c
1535 ---- freetype-orig/src/truetype/ttgload.c 2012-06-14 00:35:58.000000000 -0500
1536 -+++ freetype-subpixel/src/truetype/ttgload.c 2012-06-15 07:31:12.151985563 -0500
1537 -@@ -32,6 +32,7 @@
1538 - #endif
1539 -
1540 - #include "tterrors.h"
1541 -+#include "ttsubpix.h"
1542 -
1543 -
1544 - /*************************************************************************/
1545 -@@ -149,6 +150,15 @@
1546 - loader->top_bearing = top_bearing;
1547 - loader->vadvance = advance_height;
1548 -
1549 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1550 -+ if ( loader->exec )
1551 -+ loader->exec->sph_tweak_flags = 0;
1552 -+
1553 -+ /* this may not be the right place for this, but it works */
1554 -+ if ( loader->exec && loader->exec->ignore_x_mode )
1555 -+ sph_set_tweaks( loader, glyph_index );
1556 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1557 -+
1558 - if ( !loader->linear_def )
1559 - {
1560 - loader->linear_def = 1;
1561 -@@ -813,6 +823,13 @@
1562 - loader->pp4 = zone->cur[zone->n_points - 1];
1563 - }
1564 -
1565 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1566 -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
1567 -+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
1568 -+
1569 -+ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
1570 -+ FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
1571 -+#endif
1572 - return TT_Err_Ok;
1573 - }
1574 -
1575 -@@ -835,6 +852,13 @@
1576 - FT_Outline* outline;
1577 - FT_Int n_points;
1578 -
1579 -+ TT_Face face = (TT_Face)loader->face;
1580 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1581 -+ FT_String* family = face->root.family_name;
1582 -+ int ppem = loader->size->metrics.x_ppem;
1583 -+ FT_String* style = face->root.style_name;
1584 -+ float x_scale_factor = 1.0;
1585 -+#endif
1586 -
1587 - outline = &gloader->current.outline;
1588 - n_points = outline->n_points;
1589 -@@ -889,6 +913,26 @@
1590 - loader->zone.n_points + 4 );
1591 - }
1592 -
1593 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1594 -+ /* scale, but only if enabled and only if TT hinting is being used */
1595 -+ if ( IS_HINTED( loader->load_flags ) )
1596 -+ x_scale_factor = scale_test_tweak( face, family, ppem, style,
1597 -+ loader->glyph_index, X_SCALING_Rules,
1598 -+ X_SCALING_RULES_SIZE );
1599 -+ /* scale the glyph */
1600 -+ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1601 -+ x_scale_factor != 1.0 )
1602 -+ {
1603 -+ FT_Vector* vec = outline->points;
1604 -+ FT_Vector* limit = outline->points + n_points;
1605 -+ FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale * x_scale_factor;
1606 -+ FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
1607 -+
1608 -+ /* compensate for any scaling by de/emboldening */
1609 -+ if ( x_scale_factor != 1.0 && ppem > 11 )
1610 -+ FT_Outline_EmboldenXY( outline,
1611 -+ (FT_Int) ( 16.0 * (float)ppem * ( 1.0 - x_scale_factor) ), 0 );
1612 -+#else
1613 - /* scale the glyph */
1614 - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1615 - {
1616 -@@ -896,7 +940,7 @@
1617 - FT_Vector* limit = outline->points + n_points;
1618 - FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale;
1619 - FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale;
1620 --
1621 -+#endif
1622 -
1623 - for ( ; vec < limit; vec++ )
1624 - {
1625 -@@ -1648,12 +1692,26 @@
1626 - {
1627 - FT_Byte* widthp;
1628 -
1629 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1630 -+ FT_Bool ignore_x_mode;
1631 -+
1632 -+
1633 -+ ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
1634 -+ FT_RENDER_MODE_MONO );
1635 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1636 -
1637 - widthp = tt_face_get_device_metrics( face,
1638 - size->root.metrics.x_ppem,
1639 - glyph_index );
1640 -
1641 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1642 -+ if ( widthp &&
1643 -+ ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
1644 -+ !ignore_x_mode ||
1645 -+ SPH_OPTION_BITMAP_WIDTHS ) )
1646 -+#else
1647 - if ( widthp )
1648 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1649 - glyph->metrics.horiAdvance = *widthp << 6;
1650 - }
1651 -
1652 -@@ -1848,6 +1906,15 @@
1653 - {
1654 - TT_ExecContext exec;
1655 - FT_Bool grayscale;
1656 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1657 -+ FT_Bool subpixel_hinting;
1658 -+ FT_Bool grayscale_hinting;
1659 -+#if 0
1660 -+ FT_Bool compatible_widths;
1661 -+ FT_Bool symmetrical_smoothing;
1662 -+ FT_Bool bgr;
1663 -+#endif
1664 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1665 -
1666 -
1667 - if ( !size->cvt_ready )
1668 -@@ -1865,11 +1932,88 @@
1669 - if ( !exec )
1670 - return TT_Err_Could_Not_Find_Context;
1671 -
1672 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1673 -+
1674 -+ subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags )
1675 -+ != FT_RENDER_MODE_MONO ) &&
1676 -+ SPH_OPTION_SET_SUBPIXEL );
1677 -+
1678 -+ if ( subpixel_hinting )
1679 -+ grayscale = grayscale_hinting = FALSE;
1680 -+
1681 -+ else if ( SPH_OPTION_SET_GRAYSCALE )
1682 -+ {
1683 -+ grayscale = grayscale_hinting = TRUE;
1684 -+ subpixel_hinting = FALSE;
1685 -+ }
1686 -+
1687 -+ if ( FT_IS_TRICKY( glyph->face ) )
1688 -+ {
1689 -+ subpixel_hinting = grayscale_hinting = FALSE;
1690 -+ }
1691 -+
1692 -+ exec->ignore_x_mode = subpixel_hinting || grayscale_hinting;
1693 -+ exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
1694 -+ if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
1695 -+ exec->rasterizer_version = 35;
1696 -+
1697 -+#if 1
1698 -+ exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
1699 -+ exec->symmetrical_smoothing = FALSE;
1700 -+ exec->bgr = FALSE;
1701 -+#else /* 0 */
1702 -+ exec->compatible_widths =
1703 -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
1704 -+ TT_LOAD_COMPATIBLE_WIDTHS );
1705 -+ exec->symmetrical_smoothing =
1706 -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
1707 -+ TT_LOAD_SYMMETRICAL_SMOOTHING );
1708 -+ exec->bgr =
1709 -+ FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
1710 -+ TT_LOAD_BGR );
1711 -+#endif /* 0 */
1712 -+
1713 -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1714 -+
1715 - grayscale =
1716 - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO );
1717 -
1718 -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1719 -+
1720 - TT_Load_Context( exec, face, size );
1721 -
1722 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1723 -+
1724 -+ /* a change from mono to subpixel rendering (and vice versa) */
1725 -+ /* requires a re-execution of the CVT program */
1726 -+ if ( subpixel_hinting != exec->subpixel_hinting )
1727 -+ {
1728 -+ FT_UInt i;
1729 -+
1730 -+
1731 -+ exec->subpixel_hinting = subpixel_hinting;
1732 -+
1733 -+ for ( i = 0; i < size->cvt_size; i++ )
1734 -+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
1735 -+ tt_size_run_prep( size, pedantic );
1736 -+ }
1737 -+
1738 -+ /* a change from mono to grayscale rendering (and vice versa) */
1739 -+ /* requires a re-execution of the CVT program */
1740 -+ if ( grayscale != exec->grayscale_hinting )
1741 -+ {
1742 -+ FT_UInt i;
1743 -+
1744 -+
1745 -+ exec->grayscale_hinting = grayscale_hinting;
1746 -+
1747 -+ for ( i = 0; i < size->cvt_size; i++ )
1748 -+ size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
1749 -+ tt_size_run_prep( size, pedantic );
1750 -+ }
1751 -+
1752 -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1753 -+
1754 - /* a change from mono to grayscale rendering (and vice versa) */
1755 - /* requires a re-execution of the CVT program */
1756 - if ( grayscale != exec->grayscale )
1757 -@@ -1887,6 +2031,8 @@
1758 - tt_size_run_prep( size, pedantic );
1759 - }
1760 -
1761 -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1762 -+
1763 - /* see whether the cvt program has disabled hinting */
1764 - if ( exec->GS.instruct_control & 1 )
1765 - load_flags |= FT_LOAD_NO_HINTING;
1766 -diff -Nur freetype-orig/src/truetype/ttinterp.c freetype-subpixel/src/truetype/ttinterp.c
1767 ---- freetype-orig/src/truetype/ttinterp.c 2012-06-14 00:35:58.000000000 -0500
1768 -+++ freetype-subpixel/src/truetype/ttinterp.c 2012-06-16 10:31:47.161209856 -0500
1769 -@@ -27,13 +27,16 @@
1770 - #include FT_SYSTEM_H
1771 -
1772 - #include "ttinterp.h"
1773 --
1774 - #include "tterrors.h"
1775 -+#include "ttsubpix.h"
1776 -
1777 -
1778 - #ifdef TT_USE_BYTECODE_INTERPRETER
1779 -
1780 -
1781 -+#define xxxSPH_DEBUG
1782 -+#define xxxSPH_DEBUG_MORE_VERBOSE
1783 -+
1784 - #define TT_MULFIX FT_MulFix
1785 - #define TT_MULDIV FT_MulDiv
1786 - #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round
1787 -@@ -153,11 +156,11 @@
1788 - #define NORMalize( x, y, v ) \
1789 - Normalize( EXEC_ARG_ x, y, v )
1790 -
1791 --#define SET_SuperRound( scale, flags ) \
1792 -- SetSuperRound( EXEC_ARG_ scale, flags )
1793 -+#define SET_SuperRound( scale, flags, res ) \
1794 -+ SetSuperRound( EXEC_ARG_ scale, flags, res )
1795 -
1796 --#define ROUND_None( d, c ) \
1797 -- Round_None( EXEC_ARG_ d, c )
1798 -+#define ROUND_None( d, c, e ) \
1799 -+ Round_None( EXEC_ARG_ d, c, e )
1800 -
1801 - #define INS_Goto_CodeRange( range, ip ) \
1802 - Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
1803 -@@ -168,8 +171,8 @@
1804 - #define CUR_Func_move_orig( z, p, d ) \
1805 - CUR.func_move_orig( EXEC_ARG_ z, p, d )
1806 -
1807 --#define CUR_Func_round( d, c ) \
1808 -- CUR.func_round( EXEC_ARG_ d, c )
1809 -+#define CUR_Func_round( d, c, e ) \
1810 -+ CUR.func_round( EXEC_ARG_ d, c, e )
1811 -
1812 - #define CUR_Func_read_cvt( index ) \
1813 - CUR.func_read_cvt( EXEC_ARG_ index )
1814 -@@ -1850,6 +1853,10 @@
1815 -
1816 - if ( v != 0 )
1817 - {
1818 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1819 -+ if ( !CUR.ignore_x_mode ||
1820 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) )
1821 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1822 - zone->cur[point].x += TT_MULDIV( distance,
1823 - v * 0x10000L,
1824 - CUR.F_dot_P );
1825 -@@ -1932,6 +1939,10 @@
1826 - {
1827 - FT_UNUSED_EXEC;
1828 -
1829 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1830 -+ if ( !CUR.ignore_x_mode ||
1831 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVEX ) )
1832 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1833 - zone->cur[point].x += distance;
1834 - zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
1835 - }
1836 -@@ -1994,6 +2005,8 @@
1837 - /* */
1838 - /* compensation :: The engine compensation. */
1839 - /* */
1840 -+ /* resolution :: The number of grid lines per pixel. */
1841 -+ /* */
1842 - /* <Return> */
1843 - /* The compensated distance. */
1844 - /* */
1845 -@@ -2005,11 +2018,13 @@
1846 - /* */
1847 - static FT_F26Dot6
1848 - Round_None( EXEC_OP_ FT_F26Dot6 distance,
1849 -- FT_F26Dot6 compensation )
1850 -+ FT_F26Dot6 compensation,
1851 -+ FT_Int resolution )
1852 - {
1853 - FT_F26Dot6 val;
1854 -
1855 - FT_UNUSED_EXEC;
1856 -+ FT_UNUSED( resolution );
1857 -
1858 -
1859 - if ( distance >= 0 )
1860 -@@ -2024,6 +2039,7 @@
1861 - if ( val > 0 )
1862 - val = 0;
1863 - }
1864 -+
1865 - return val;
1866 - }
1867 -
1868 -@@ -2041,12 +2057,15 @@
1869 - /* */
1870 - /* compensation :: The engine compensation. */
1871 - /* */
1872 -+ /* resolution :: The number of grid lines per pixel. */
1873 -+ /* */
1874 - /* <Return> */
1875 - /* Rounded distance. */
1876 - /* */
1877 - static FT_F26Dot6
1878 - Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
1879 -- FT_F26Dot6 compensation )
1880 -+ FT_F26Dot6 compensation,
1881 -+ FT_Int resolution )
1882 - {
1883 - FT_F26Dot6 val;
1884 -
1885 -@@ -2055,15 +2074,15 @@
1886 -
1887 - if ( distance >= 0 )
1888 - {
1889 -- val = distance + compensation + 32;
1890 -+ val = distance + compensation + 32 / resolution;
1891 - if ( distance && val > 0 )
1892 -- val &= ~63;
1893 -+ val &= ~( 64 / resolution - 1 );
1894 - else
1895 - val = 0;
1896 - }
1897 - else
1898 - {
1899 -- val = -FT_PIX_ROUND( compensation - distance );
1900 -+ val = -FT_PIX_ROUND_GRID( compensation - distance, resolution );
1901 - if ( val > 0 )
1902 - val = 0;
1903 - }
1904 -@@ -2085,12 +2104,15 @@
1905 - /* */
1906 - /* compensation :: The engine compensation. */
1907 - /* */
1908 -+ /* resolution :: The number of grid lines per pixel. */
1909 -+ /* */
1910 - /* <Return> */
1911 - /* Rounded distance. */
1912 - /* */
1913 - static FT_F26Dot6
1914 - Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance,
1915 -- FT_F26Dot6 compensation )
1916 -+ FT_F26Dot6 compensation,
1917 -+ FT_Int resolution )
1918 - {
1919 - FT_F26Dot6 val;
1920 -
1921 -@@ -2099,13 +2121,15 @@
1922 -
1923 - if ( distance >= 0 )
1924 - {
1925 -- val = FT_PIX_FLOOR( distance + compensation ) + 32;
1926 -+ val = FT_PIX_FLOOR_GRID( distance + compensation, resolution ) +
1927 -+ 32 / resolution;
1928 - if ( distance && val < 0 )
1929 - val = 0;
1930 - }
1931 - else
1932 - {
1933 -- val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
1934 -+ val = -( FT_PIX_FLOOR_GRID( compensation - distance, resolution ) +
1935 -+ 32 / resolution );
1936 - if ( val > 0 )
1937 - val = 0;
1938 - }
1939 -@@ -2127,12 +2151,15 @@
1940 - /* */
1941 - /* compensation :: The engine compensation. */
1942 - /* */
1943 -+ /* resolution :: The number of grid lines per pixel. */
1944 -+ /* */
1945 - /* <Return> */
1946 - /* Rounded distance. */
1947 - /* */
1948 - static FT_F26Dot6
1949 - Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
1950 -- FT_F26Dot6 compensation )
1951 -+ FT_F26Dot6 compensation,
1952 -+ FT_Int resolution )
1953 - {
1954 - FT_F26Dot6 val;
1955 -
1956 -@@ -2143,13 +2170,13 @@
1957 - {
1958 - val = distance + compensation;
1959 - if ( distance && val > 0 )
1960 -- val &= ~63;
1961 -+ val &= ~( 64 / resolution - 1 );
1962 - else
1963 - val = 0;
1964 - }
1965 - else
1966 - {
1967 -- val = -( ( compensation - distance ) & -64 );
1968 -+ val = -( ( compensation - distance ) & -( 64 / resolution ) );
1969 - if ( val > 0 )
1970 - val = 0;
1971 - }
1972 -@@ -2171,12 +2198,15 @@
1973 - /* */
1974 - /* compensation :: The engine compensation. */
1975 - /* */
1976 -+ /* resolution :: The number of grid lines per pixel. */
1977 -+ /* */
1978 - /* <Return> */
1979 - /* Rounded distance. */
1980 - /* */
1981 - static FT_F26Dot6
1982 - Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
1983 -- FT_F26Dot6 compensation )
1984 -+ FT_F26Dot6 compensation,
1985 -+ FT_Int resolution )
1986 - {
1987 - FT_F26Dot6 val;
1988 -
1989 -@@ -2185,15 +2215,15 @@
1990 -
1991 - if ( distance >= 0 )
1992 - {
1993 -- val = distance + compensation + 63;
1994 -+ val = distance + compensation + ( 64 / resolution - 1 );
1995 - if ( distance && val > 0 )
1996 -- val &= ~63;
1997 -+ val &= ~( 64 / resolution - 1 );
1998 - else
1999 - val = 0;
2000 - }
2001 - else
2002 - {
2003 -- val = - FT_PIX_CEIL( compensation - distance );
2004 -+ val = -FT_PIX_CEIL_GRID( compensation - distance, resolution );
2005 - if ( val > 0 )
2006 - val = 0;
2007 - }
2008 -@@ -2215,12 +2245,15 @@
2009 - /* */
2010 - /* compensation :: The engine compensation. */
2011 - /* */
2012 -+ /* resolution :: The number of grid lines per pixel. */
2013 -+ /* */
2014 - /* <Return> */
2015 - /* Rounded distance. */
2016 - /* */
2017 - static FT_F26Dot6
2018 - Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance,
2019 -- FT_F26Dot6 compensation )
2020 -+ FT_F26Dot6 compensation,
2021 -+ FT_Int resolution )
2022 - {
2023 - FT_F26Dot6 val;
2024 -
2025 -@@ -2229,15 +2262,15 @@
2026 -
2027 - if ( distance >= 0 )
2028 - {
2029 -- val = distance + compensation + 16;
2030 -+ val = distance + compensation + 16 / resolution;
2031 - if ( distance && val > 0 )
2032 -- val &= ~31;
2033 -+ val &= ~( 32 / resolution - 1 );
2034 - else
2035 - val = 0;
2036 - }
2037 - else
2038 - {
2039 -- val = -FT_PAD_ROUND( compensation - distance, 32 );
2040 -+ val = -FT_PAD_ROUND( compensation - distance, 32 / resolution );
2041 - if ( val > 0 )
2042 - val = 0;
2043 - }
2044 -@@ -2259,6 +2292,8 @@
2045 - /* */
2046 - /* compensation :: The engine compensation. */
2047 - /* */
2048 -+ /* resolution :: The number of grid lines per pixel. */
2049 -+ /* */
2050 - /* <Return> */
2051 - /* Rounded distance. */
2052 - /* */
2053 -@@ -2270,10 +2305,13 @@
2054 - /* */
2055 - static FT_F26Dot6
2056 - Round_Super( EXEC_OP_ FT_F26Dot6 distance,
2057 -- FT_F26Dot6 compensation )
2058 -+ FT_F26Dot6 compensation,
2059 -+ FT_Int resolution )
2060 - {
2061 - FT_F26Dot6 val;
2062 -
2063 -+ FT_UNUSED( resolution );
2064 -+
2065 -
2066 - if ( distance >= 0 )
2067 - {
2068 -@@ -2309,6 +2347,8 @@
2069 - /* */
2070 - /* compensation :: The engine compensation. */
2071 - /* */
2072 -+ /* resolution :: The number of grid lines per pixel. */
2073 -+ /* */
2074 - /* <Return> */
2075 - /* Rounded distance. */
2076 - /* */
2077 -@@ -2318,10 +2358,13 @@
2078 - /* */
2079 - static FT_F26Dot6
2080 - Round_Super_45( EXEC_OP_ FT_F26Dot6 distance,
2081 -- FT_F26Dot6 compensation )
2082 -+ FT_F26Dot6 compensation,
2083 -+ FT_Int resolution )
2084 - {
2085 - FT_F26Dot6 val;
2086 -
2087 -+ FT_UNUSED( resolution );
2088 -+
2089 -
2090 - if ( distance >= 0 )
2091 - {
2092 -@@ -2404,13 +2447,19 @@
2093 - /* Sets Super Round parameters. */
2094 - /* */
2095 - /* <Input> */
2096 -- /* GridPeriod :: Grid period */
2097 -- /* selector :: SROUND opcode */
2098 -+ /* GridPeriod :: The grid period. */
2099 -+ /* */
2100 -+ /* selector :: The SROUND opcode. */
2101 -+ /* */
2102 -+ /* resolution :: The number of grid lines per pixel. */
2103 - /* */
2104 - static void
2105 - SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod,
2106 -- FT_Long selector )
2107 -+ FT_Long selector,
2108 -+ FT_Int resolution )
2109 - {
2110 -+ FT_UNUSED( resolution );
2111 -+
2112 - switch ( (FT_Int)( selector & 0xC0 ) )
2113 - {
2114 - case 0:
2115 -@@ -3080,13 +3129,13 @@
2116 -
2117 -
2118 - #define DO_SROUND \
2119 -- SET_SuperRound( 0x4000, args[0] ); \
2120 -+ SET_SuperRound( 0x4000, args[0], 1 ); \
2121 - CUR.GS.round_state = TT_Round_Super; \
2122 - CUR.func_round = (TT_Round_Func)Round_Super;
2123 -
2124 -
2125 - #define DO_S45ROUND \
2126 -- SET_SuperRound( 0x2D41, args[0] ); \
2127 -+ SET_SuperRound( 0x2D41, args[0], 1 ); \
2128 - CUR.GS.round_state = TT_Round_Super_45; \
2129 - CUR.func_round = (TT_Round_Func)Round_Super_45;
2130 -
2131 -@@ -3257,12 +3306,12 @@
2132 - args[0] = ( args[0] != args[1] );
2133 -
2134 -
2135 --#define DO_ODD \
2136 -- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
2137 -+#define DO_ODD \
2138 -+ args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 64 );
2139 -
2140 -
2141 --#define DO_EVEN \
2142 -- args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
2143 -+#define DO_EVEN \
2144 -+ args[0] = ( ( CUR_Func_round( args[0], 0, 1 ) & 127 ) == 0 );
2145 -
2146 -
2147 - #define DO_AND \
2148 -@@ -3311,6 +3360,34 @@
2149 - #define DO_CEILING \
2150 - args[0] = FT_PIX_CEIL( args[0] );
2151 -
2152 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2153 -+
2154 -+#define DO_RS \
2155 -+ { \
2156 -+ FT_ULong I = (FT_ULong)args[0]; \
2157 -+ \
2158 -+ \
2159 -+ if ( BOUNDSL( I, CUR.storeSize ) ) \
2160 -+ { \
2161 -+ if ( CUR.pedantic_hinting ) \
2162 -+ ARRAY_BOUND_ERROR; \
2163 -+ else \
2164 -+ args[0] = 0; \
2165 -+ } \
2166 -+ else \
2167 -+ { \
2168 -+ /* subpixel hinting - avoid Typeman Dstroke and */ \
2169 -+ /* IStroke and Vacuform rounds */ \
2170 -+ \
2171 -+ if ( CUR.compatibility_mode && \
2172 -+ ( I == 24 || I == 22 || I == 8 ) ) \
2173 -+ args[0] = 0; \
2174 -+ else \
2175 -+ args[0] = CUR.storage[I]; \
2176 -+ } \
2177 -+ }
2178 -+
2179 -+#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2180 -
2181 - #define DO_RS \
2182 - { \
2183 -@@ -3330,6 +3407,8 @@
2184 - args[0] = CUR.storage[I]; \
2185 - }
2186 -
2187 -+#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2188 -+
2189 -
2190 - #define DO_WS \
2191 - { \
2192 -@@ -3405,15 +3484,17 @@
2193 - CUR.error = TT_Err_Debug_OpCode;
2194 -
2195 -
2196 --#define DO_ROUND \
2197 -- args[0] = CUR_Func_round( \
2198 -- args[0], \
2199 -- CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
2200 -+#define DO_ROUND \
2201 -+ args[0] = CUR_Func_round( \
2202 -+ args[0], \
2203 -+ CUR.tt_metrics.compensations[CUR.opcode - 0x68], \
2204 -+ 1 );
2205 -
2206 -
2207 --#define DO_NROUND \
2208 -- args[0] = ROUND_None( args[0], \
2209 -- CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
2210 -+#define DO_NROUND \
2211 -+ args[0] = ROUND_None( args[0], \
2212 -+ CUR.tt_metrics.compensations[CUR.opcode - 0x6C], \
2213 -+ 1 );
2214 -
2215 -
2216 - #define DO_MAX \
2217 -@@ -4587,6 +4668,24 @@
2218 - TT_DefRecord* rec;
2219 - TT_DefRecord* limit;
2220 -
2221 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2222 -+#if 0
2223 -+ int opcode_pattern[4][12] = {
2224 -+ /* VacuFormRound function */
2225 -+ {0x45,0x23,0x46,0x60,0x20},
2226 -+ /* inline delta function 1 */
2227 -+ {0x4B,0x53,0x23,0x4B,0x51,0x5A,0x58,0x38,0x1B,0x21,0x21,0x59},
2228 -+ /* inline delta function 2 */
2229 -+ {0x4B,0x54,0x58,0x38,0x1B,0x5A,0x21,0x21,0x59},
2230 -+ /* diagonal stroke function */
2231 -+ {0x20,0x20,0x40,0x60,0x47,0x40,0x23,0x42},
2232 -+ };
2233 -+ int opcode_patterns = 4;
2234 -+ int i;
2235 -+ int opcode_pointer[4] = {0,0,0,0};
2236 -+#endif
2237 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2238 -+
2239 -
2240 - /* some font programs are broken enough to redefine functions! */
2241 - /* We will then parse the current table. */
2242 -@@ -4620,10 +4719,11 @@
2243 - return;
2244 - }
2245 -
2246 -- rec->range = CUR.curRange;
2247 -- rec->opc = (FT_UInt16)n;
2248 -- rec->start = CUR.IP + 1;
2249 -- rec->active = TRUE;
2250 -+ rec->range = CUR.curRange;
2251 -+ rec->opc = (FT_UInt16)n;
2252 -+ rec->start = CUR.IP + 1;
2253 -+ rec->active = TRUE;
2254 -+ rec->inline_delta = FALSE;
2255 -
2256 - if ( n > CUR.maxFunc )
2257 - CUR.maxFunc = (FT_UInt16)n;
2258 -@@ -4633,6 +4733,78 @@
2259 -
2260 - while ( SKIP_Code() == SUCCESS )
2261 - {
2262 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2263 -+#if 0
2264 -+#ifdef SPH_DEBUG_MORE_VERBOSE
2265 -+ printf ("Opcode: %d ", CUR.opcode);
2266 -+#endif
2267 -+
2268 -+ for ( i = 0; i < opcode_patterns; i++ )
2269 -+ {
2270 -+ if ( CUR.opcode == opcode_pattern[i][opcode_pointer[i]] )
2271 -+ {
2272 -+#ifdef SPH_DEBUG_MORE_VERBOSE
2273 -+ printf( "function %d, opcode ptrn: %d"
2274 -+ " op# %d: %d FOUND \n",
2275 -+ n, i, opcode_pointer[i], CUR.opcode );
2276 -+#endif
2277 -+ opcode_pointer[i] += 1;
2278 -+
2279 -+ if ( i == 0 && opcode_pointer[0] == 5 )
2280 -+ {
2281 -+
2282 -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n;
2283 -+ CUR.num_delta_funcs++;
2284 -+#ifdef SPH_DEBUG
2285 -+ printf( "Vacuform Round FUNCTION %d detected\n", n);
2286 -+#endif
2287 -+ /*rec->active = FALSE;*/
2288 -+ opcode_pointer[i] = 0;
2289 -+ }
2290 -+
2291 -+ if ( i == 1 && opcode_pointer[1] == 12 )
2292 -+ {
2293 -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n;
2294 -+ CUR.num_delta_funcs++;
2295 -+#ifdef SPH_DEBUG
2296 -+ printf( "inline delta FUNCTION1 %d detected\n",
2297 -+ n, CUR.num_delta_funcs);
2298 -+#endif
2299 -+ rec->inline_delta = TRUE;
2300 -+ opcode_pointer[i] = 0;
2301 -+ }
2302 -+
2303 -+ if ( i == 2 && opcode_pointer[1] == 9 )
2304 -+ {
2305 -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n;
2306 -+ CUR.num_delta_funcs++;
2307 -+ rec->inline_delta = TRUE;
2308 -+#ifdef SPH_DEBUG
2309 -+ printf( "inline delta2 FUNCTION2 %d detected\n",
2310 -+ n, CUR.num_delta_funcs);
2311 -+#endif
2312 -+ opcode_pointer[i] = 0;
2313 -+ }
2314 -+
2315 -+ if ( i == 4 && opcode_pointer[1] == 8 )
2316 -+ {
2317 -+ CUR.inline_delta_funcs[CUR.num_delta_funcs] = n;
2318 -+ CUR.num_delta_funcs++;
2319 -+ /*rec->active = FALSE;*/
2320 -+#ifdef SPH_DEBUG
2321 -+ printf( "diagonal stroke function %d detected\n",
2322 -+ n, CUR.num_delta_funcs);
2323 -+#endif
2324 -+ opcode_pointer[i] = 0;
2325 -+ }
2326 -+ }
2327 -+
2328 -+ else
2329 -+ opcode_pointer[i] = 0;
2330 -+ }
2331 -+#endif
2332 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2333 -+
2334 - switch ( CUR.opcode )
2335 - {
2336 - case 0x89: /* IDEF */
2337 -@@ -4676,6 +4848,15 @@
2338 -
2339 - CUR.step_ins = FALSE;
2340 -
2341 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2342 -+ /*
2343 -+ * CUR.ignore_x_mode may be turned off prior to function calls. This
2344 -+ * ensures it is turned back on.
2345 -+ */
2346 -+ CUR.ignore_x_mode = ( CUR.subpixel_hinting || CUR.grayscale_hinting )
2347 -+ && !( CUR.sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING );
2348 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2349 -+
2350 - if ( pRec->Cur_Count > 0 )
2351 - {
2352 - CUR.callTop++;
2353 -@@ -4709,6 +4890,10 @@
2354 - TT_CallRec* pCrec;
2355 - TT_DefRecord* def;
2356 -
2357 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2358 -+ FT_Bool oldF;
2359 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2360 -+
2361 -
2362 - /* first of all, check the index */
2363 -
2364 -@@ -4746,6 +4931,20 @@
2365 - if ( !def->active )
2366 - goto Fail;
2367 -
2368 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2369 -+ /* This is test code used to detect inline delta functions */
2370 -+ oldF = def->inline_delta;
2371 -+ if ( CUR.ignore_x_mode )
2372 -+ {
2373 -+ if ( def->inline_delta )
2374 -+ CUR.in_delta_function = TRUE;
2375 -+ }
2376 -+
2377 -+#ifdef SPH_DEBUG
2378 -+ printf("Entering function %d\n", F);
2379 -+#endif
2380 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2381 -+
2382 - /* check the call stack */
2383 - if ( CUR.callTop >= CUR.callSize )
2384 - {
2385 -@@ -4767,6 +4966,13 @@
2386 - def->start );
2387 -
2388 - CUR.step_ins = FALSE;
2389 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2390 -+ CUR.in_delta_function = oldF;
2391 -+
2392 -+#ifdef SPH_DEBUG
2393 -+ printf("Leaving function %d\n", F);
2394 -+#endif
2395 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2396 - return;
2397 -
2398 - Fail:
2399 -@@ -4787,6 +4993,10 @@
2400 - TT_CallRec* pCrec;
2401 - TT_DefRecord* def;
2402 -
2403 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2404 -+ FT_Bool oldF;
2405 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2406 -+
2407 -
2408 - /* first of all, check the index */
2409 - F = args[1];
2410 -@@ -4823,6 +5033,15 @@
2411 - if ( !def->active )
2412 - goto Fail;
2413 -
2414 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2415 -+ oldF = def->inline_delta;
2416 -+ if ( CUR.ignore_x_mode )
2417 -+ {
2418 -+ if ( def->inline_delta )
2419 -+ CUR.in_delta_function = TRUE;
2420 -+ }
2421 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2422 -+
2423 - /* check stack */
2424 - if ( CUR.callTop >= CUR.callSize )
2425 - {
2426 -@@ -4846,6 +5065,11 @@
2427 -
2428 - CUR.step_ins = FALSE;
2429 - }
2430 -+
2431 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2432 -+ CUR.in_delta_function = oldF;
2433 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2434 -+
2435 - return;
2436 -
2437 - Fail:
2438 -@@ -5195,6 +5419,12 @@
2439 - }
2440 - }
2441 -
2442 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2443 -+ /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
2444 -+ if ( CUR.ignore_x_mode && FT_ABS( D ) == 64 )
2445 -+ D += 1;
2446 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2447 -+
2448 - args[0] = D;
2449 - }
2450 -
2451 -@@ -5691,7 +5921,12 @@
2452 -
2453 - if ( CUR.GS.freeVector.x != 0 )
2454 - {
2455 -- CUR.zp2.cur[point].x += dx;
2456 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2457 -+ if ( !CUR.ignore_x_mode ||
2458 -+ ( CUR.ignore_x_mode &&
2459 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_MOVE_ZP2 ) ) )
2460 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2461 -+ CUR.zp2.cur[point].x += dx;
2462 - if ( touch )
2463 - CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
2464 - }
2465 -@@ -5872,6 +6107,9 @@
2466 - {
2467 - FT_F26Dot6 dx, dy;
2468 - FT_UShort point;
2469 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2470 -+ FT_Int B1, B2;
2471 -+#endif
2472 -
2473 -
2474 - if ( CUR.top < CUR.GS.loop + 1 )
2475 -@@ -5917,7 +6155,77 @@
2476 - }
2477 - }
2478 - else
2479 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2480 -+ {
2481 -+ /* If not using ignore_x_mode rendering, allow ZP2 move. */
2482 -+ /* If inline deltas aren't allowed, skip ZP2 move. */
2483 -+ /* If using ignore_x_mode rendering, allow ZP2 point move if: */
2484 -+ /* - freedom vector is y and compatibility_mode is off */
2485 -+ /* - the glyph is composite and the move is in the Y direction */
2486 -+ /* - the glyph is specifically set to allow SHPIX moves */
2487 -+ /* - the move is on a previously Y-touched point */
2488 -+
2489 -+ if ( CUR.ignore_x_mode )
2490 -+ {
2491 -+ /* save point for later comparison */
2492 -+ if ( CUR.GS.freeVector.y != 0 )
2493 -+ B1 = CUR.zp2.cur[point].y;
2494 -+ else
2495 -+ B1 = CUR.zp2.cur[point].x;
2496 -+
2497 -+ if ( CUR.GS.freeVector.y != 0 &&
2498 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_INLINE_DELTAS ) )
2499 -+ goto Skip;
2500 -+
2501 -+ if ( CUR.ignore_x_mode &&
2502 -+ !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 )
2503 -+ MOVE_Zp2_Point( point, dx, dy, TRUE );
2504 -+
2505 -+ else if ( CUR.ignore_x_mode && CUR.compatibility_mode )
2506 -+ {
2507 -+ if ( CUR.ignore_x_mode &&
2508 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
2509 -+ {
2510 -+ dx = FT_PIX_ROUND ( B1 + dx ) - B1;
2511 -+ dy = FT_PIX_ROUND ( B1 + dy ) - B1;
2512 -+ }
2513 -+
2514 -+ if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
2515 -+ ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ||
2516 -+ ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ||
2517 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) )
2518 -+ )
2519 -+ MOVE_Zp2_Point( point, dx, dy, TRUE );
2520 -+ }
2521 -+
2522 -+ /* save new point */
2523 -+ if ( CUR.GS.freeVector.y != 0 )
2524 -+ B2 = CUR.zp2.cur[point].y;
2525 -+ else B2 = CUR.zp2.cur[point].x;
2526 -+
2527 -+ /* reverse any disallowed moves */
2528 -+ if ( ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
2529 -+ CUR.GS.freeVector.y != 0 &&
2530 -+ B1 % 64 != 0 &&
2531 -+ B2 % 64 != 0 && B1 != B2 ) ||
2532 -+ ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
2533 -+ CUR.GS.freeVector.y != 0 &&
2534 -+ B1 % 64 == 0 &&
2535 -+ B2 % 64 != 0 && B1 != B2 ) )
2536 -+ {
2537 -+#ifdef SPH_DEBUG
2538 -+ printf( "Reversing ZP2 move\n" );
2539 -+#endif
2540 -+ MOVE_Zp2_Point( point, -dx, -dy, TRUE );
2541 -+ }
2542 -+ }
2543 -+ else
2544 -+ MOVE_Zp2_Point( point, dx, dy, TRUE );
2545 -+ }
2546 -+ Skip:
2547 -+#else
2548 - MOVE_Zp2_Point( point, dx, dy, TRUE );
2549 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2550 -
2551 - CUR.GS.loop--;
2552 - }
2553 -@@ -5939,7 +6247,18 @@
2554 - {
2555 - FT_UShort point;
2556 - FT_F26Dot6 distance;
2557 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2558 -+ FT_Int gridlines_per_pixel = 1;
2559 -+
2560 -
2561 -+ if ( CUR.ignore_x_mode )
2562 -+ {
2563 -+ if ( CUR.GS.freeVector.x != 0 )
2564 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X;
2565 -+ else if ( CUR.GS.freeVector.y != 0 )
2566 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y;
2567 -+ }
2568 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2569 -
2570 - point = (FT_UShort)args[0];
2571 -
2572 -@@ -5963,6 +6282,15 @@
2573 - distance = CUR_Func_project( CUR.zp1.cur + point,
2574 - CUR.zp0.cur + CUR.GS.rp0 );
2575 -
2576 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2577 -+ /* subpixel hinting - make MSIRP respect CVT cut-in; */
2578 -+ if ( CUR.ignore_x_mode &&
2579 -+ CUR.GS.freeVector.x != 0 &&
2580 -+ FT_ABS( distance - args[1] ) >=
2581 -+ CUR.GS.control_value_cutin / gridlines_per_pixel )
2582 -+ distance = args[1];
2583 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2584 -+
2585 - CUR_Func_move( &CUR.zp1, point, args[1] - distance );
2586 -
2587 - CUR.GS.rp1 = CUR.GS.rp0;
2588 -@@ -5985,7 +6313,21 @@
2589 - FT_UShort point;
2590 - FT_F26Dot6 cur_dist,
2591 - distance;
2592 -+ FT_Int gridlines_per_pixel = 1;
2593 -+
2594 -
2595 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2596 -+ if ( CUR.ignore_x_mode )
2597 -+ {
2598 -+ if ( CUR.GS.freeVector.x != 0 &&
2599 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2600 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X;
2601 -+
2602 -+ else if ( CUR.GS.freeVector.y != 0 &&
2603 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2604 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y;
2605 -+ }
2606 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2607 -
2608 - point = (FT_UShort)args[0];
2609 -
2610 -@@ -6000,7 +6342,8 @@
2611 - {
2612 - cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
2613 - distance = CUR_Func_round( cur_dist,
2614 -- CUR.tt_metrics.compensations[0] ) - cur_dist;
2615 -+ CUR.tt_metrics.compensations[0],
2616 -+ gridlines_per_pixel ) - cur_dist;
2617 - }
2618 - else
2619 - distance = 0;
2620 -@@ -6025,8 +6368,22 @@
2621 - FT_UShort point;
2622 - FT_F26Dot6 distance,
2623 - org_dist;
2624 -+ FT_Int gridlines_per_pixel = 1;
2625 -
2626 -
2627 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2628 -+ if ( CUR.ignore_x_mode )
2629 -+ {
2630 -+ if ( CUR.GS.freeVector.x != 0 &&
2631 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2632 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X;
2633 -+
2634 -+ else if ( CUR.GS.freeVector.y != 0 &&
2635 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2636 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y;
2637 -+ }
2638 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2639 -+
2640 - cvtEntry = (FT_ULong)args[1];
2641 - point = (FT_UShort)args[0];
2642 -
2643 -@@ -6062,21 +6419,34 @@
2644 -
2645 - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */
2646 - {
2647 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2648 -+ /* only adjust legacy fonts x otherwise breaks Calibri italic */
2649 -+ if ( CUR.compatibility_mode )
2650 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2651 - CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
2652 - CUR.GS.freeVector.x );
2653 - CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
2654 - CUR.GS.freeVector.y ),
2655 - CUR.zp0.cur[point] = CUR.zp0.org[point];
2656 - }
2657 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2658 -+ if ( distance > 0 &&
2659 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
2660 -+ CUR.GS.freeVector.y != 0 )
2661 -+ distance = 0 ;
2662 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2663 -
2664 - org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
2665 -
2666 - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */
2667 - {
2668 -- if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin )
2669 -+ if ( FT_ABS( distance - org_dist ) >
2670 -+ CUR.GS.control_value_cutin / gridlines_per_pixel )
2671 - distance = org_dist;
2672 -
2673 -- distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );
2674 -+ distance = CUR_Func_round( distance,
2675 -+ CUR.tt_metrics.compensations[0],
2676 -+ gridlines_per_pixel );
2677 - }
2678 -
2679 - CUR_Func_move( &CUR.zp0, point, distance - org_dist );
2680 -@@ -6098,6 +6468,24 @@
2681 - {
2682 - FT_UShort point;
2683 - FT_F26Dot6 org_dist, distance;
2684 -+ FT_Int minimum_distance_factor = 64;
2685 -+ FT_Int gridlines_per_pixel = 1;
2686 -+
2687 -+
2688 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2689 -+ if ( CUR.ignore_x_mode )
2690 -+ {
2691 -+ if ( CUR.GS.freeVector.x != 0 &&
2692 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2693 -+ {
2694 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X;
2695 -+ minimum_distance_factor = 64 - gridlines_per_pixel / 3;
2696 -+ }
2697 -+ else if ( CUR.GS.freeVector.y != 0 &&
2698 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2699 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y;
2700 -+ }
2701 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2702 -
2703 -
2704 - point = (FT_UShort)args[0];
2705 -@@ -6163,11 +6551,13 @@
2706 - if ( ( CUR.opcode & 4 ) != 0 )
2707 - distance = CUR_Func_round(
2708 - org_dist,
2709 -- CUR.tt_metrics.compensations[CUR.opcode & 3] );
2710 -+ CUR.tt_metrics.compensations[CUR.opcode & 3],
2711 -+ gridlines_per_pixel );
2712 - else
2713 - distance = ROUND_None(
2714 - org_dist,
2715 -- CUR.tt_metrics.compensations[CUR.opcode & 3] );
2716 -+ CUR.tt_metrics.compensations[CUR.opcode & 3],
2717 -+ gridlines_per_pixel );
2718 -
2719 - /* minimum distance flag */
2720 -
2721 -@@ -6175,13 +6565,17 @@
2722 - {
2723 - if ( org_dist >= 0 )
2724 - {
2725 -- if ( distance < CUR.GS.minimum_distance )
2726 -- distance = CUR.GS.minimum_distance;
2727 -+ if ( distance < FT_MulDiv( minimum_distance_factor,
2728 -+ CUR.GS.minimum_distance, 64 ) )
2729 -+ distance = FT_MulDiv( minimum_distance_factor,
2730 -+ CUR.GS.minimum_distance, 64 );
2731 - }
2732 - else
2733 - {
2734 -- if ( distance > -CUR.GS.minimum_distance )
2735 -- distance = -CUR.GS.minimum_distance;
2736 -+ if ( distance > -FT_MulDiv( minimum_distance_factor,
2737 -+ CUR.GS.minimum_distance, 64 ) )
2738 -+ distance = -FT_MulDiv( minimum_distance_factor,
2739 -+ CUR.GS.minimum_distance, 64 );
2740 - }
2741 - }
2742 -
2743 -@@ -6218,10 +6612,37 @@
2744 - cur_dist,
2745 - org_dist;
2746 -
2747 -+ FT_Int minimum_distance_factor = 64;
2748 -+ FT_Int gridlines_per_pixel = 1;
2749 -+
2750 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2751 -+ FT_Int B1;
2752 -+ FT_Int B2;
2753 -+ FT_Bool reverse_move = FALSE;
2754 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2755 -
2756 - point = (FT_UShort)args[0];
2757 - cvtEntry = (FT_ULong)( args[1] + 1 );
2758 -
2759 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2760 -+ if ( CUR.ignore_x_mode )
2761 -+ {
2762 -+ if ( CUR.GS.freeVector.x != 0 &&
2763 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2764 -+ {
2765 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_X;
2766 -+ /* high value emboldens glyphs at lower ppems (< 14); */
2767 -+ /* Courier looks better with 52 -- */
2768 -+ /* MS ClearType Rasterizer supposedly uses 32 */
2769 -+ minimum_distance_factor = 64 - gridlines_per_pixel / 3;
2770 -+ }
2771 -+
2772 -+ else if ( CUR.GS.freeVector.y != 0 &&
2773 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
2774 -+ gridlines_per_pixel = SPH_OPTION_GRIDLINES_PER_PIXEL_Y;
2775 -+ }
2776 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2777 -+
2778 - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
2779 -
2780 - if ( BOUNDS( point, CUR.zp1.n_points ) ||
2781 -@@ -6237,6 +6658,10 @@
2782 - cvt_dist = 0;
2783 - else
2784 - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
2785 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2786 -+ if ( CUR.sph_tweak_flags & SPH_TWEAK_MIRP_CVT_ZERO )
2787 -+ cvt_dist = 0;
2788 -+#endif
2789 -
2790 - /* single width test */
2791 -
2792 -@@ -6274,8 +6699,15 @@
2793 - if ( ( org_dist ^ cvt_dist ) < 0 )
2794 - cvt_dist = -cvt_dist;
2795 - }
2796 --
2797 -- /* control value cutin and round */
2798 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2799 -+ if ( CUR.GS.freeVector.y != 0 &&
2800 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
2801 -+ {
2802 -+ if ( cur_dist < -64 ) cvt_dist -= 16;
2803 -+ else if ( cur_dist > 64 && cur_dist < 84) cvt_dist += 32;
2804 -+ }
2805 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2806 -+ /* control value cut-in and round */
2807 -
2808 - if ( ( CUR.opcode & 4 ) != 0 )
2809 - {
2810 -@@ -6296,18 +6728,21 @@
2811 - /* `ttinst2.doc', version 1.66, is thus incorrect since */
2812 - /* it implies `>=' instead of `>'. */
2813 -
2814 -- if ( FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin )
2815 -+ if ( FT_ABS( cvt_dist - org_dist ) >
2816 -+ CUR.GS.control_value_cutin / gridlines_per_pixel )
2817 - cvt_dist = org_dist;
2818 - }
2819 -
2820 - distance = CUR_Func_round(
2821 - cvt_dist,
2822 -- CUR.tt_metrics.compensations[CUR.opcode & 3] );
2823 -+ CUR.tt_metrics.compensations[CUR.opcode & 3],
2824 -+ gridlines_per_pixel );
2825 - }
2826 - else
2827 - distance = ROUND_None(
2828 - cvt_dist,
2829 -- CUR.tt_metrics.compensations[CUR.opcode & 3] );
2830 -+ CUR.tt_metrics.compensations[CUR.opcode & 3],
2831 -+ gridlines_per_pixel );
2832 -
2833 - /* minimum distance test */
2834 -
2835 -@@ -6315,18 +6750,63 @@
2836 - {
2837 - if ( org_dist >= 0 )
2838 - {
2839 -- if ( distance < CUR.GS.minimum_distance )
2840 -- distance = CUR.GS.minimum_distance;
2841 -+ if ( distance < FT_MulDiv( minimum_distance_factor,
2842 -+ CUR.GS.minimum_distance, 64 ) )
2843 -+ distance = FT_MulDiv( minimum_distance_factor,
2844 -+ CUR.GS.minimum_distance, 64 );
2845 - }
2846 - else
2847 - {
2848 -- if ( distance > -CUR.GS.minimum_distance )
2849 -- distance = -CUR.GS.minimum_distance;
2850 -+ if ( distance > -FT_MulDiv( minimum_distance_factor,
2851 -+ CUR.GS.minimum_distance, 64 ) )
2852 -+ distance = -FT_MulDiv( minimum_distance_factor,
2853 -+ CUR.GS.minimum_distance, 64 );
2854 - }
2855 - }
2856 -
2857 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2858 -+ B1 = CUR.zp1.cur[point].y;
2859 -+
2860 -+ /* Round moves if necessary */
2861 -+ if ( CUR.ignore_x_mode &&
2862 -+ CUR.GS.freeVector.y != 0 &&
2863 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
2864 -+ distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
2865 -+
2866 -+ if ( CUR.GS.freeVector.y != 0 &&
2867 -+ ( CUR.opcode & 16 ) == 0 &&
2868 -+ ( CUR.opcode & 8 ) == 0 &&
2869 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
2870 -+ distance +=64;
2871 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2872 -+
2873 - CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
2874 -
2875 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2876 -+ B2 = CUR.zp1.cur[point].y;
2877 -+
2878 -+ /* Reverse move if necessary */
2879 -+ if ( CUR.ignore_x_mode )
2880 -+ {
2881 -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
2882 -+ CUR.GS.freeVector.y != 0 && B1 % 64 == 0 && B2 % 64 != 0 )
2883 -+ reverse_move = TRUE;
2884 -+
2885 -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
2886 -+ CUR.GS.freeVector.y != 0 && B2 % 64 != 0 && B1 % 64 != 0 )
2887 -+ reverse_move = TRUE;
2888 -+
2889 -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES ) &&
2890 -+ !reverse_move &&
2891 -+ abs ( B1 - B2 ) >= 64 )
2892 -+ reverse_move = TRUE;
2893 -+ }
2894 -+
2895 -+ if ( reverse_move )
2896 -+ CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) );
2897 -+
2898 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2899 -+
2900 - Fail:
2901 - CUR.GS.rp1 = CUR.GS.rp0;
2902 -
2903 -@@ -6350,8 +6830,14 @@
2904 - FT_F26Dot6 distance;
2905 -
2906 - FT_UNUSED_ARG;
2907 --
2908 --
2909 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2910 -+ if ( CUR.ignore_x_mode && CUR.iup_called &&
2911 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
2912 -+ {
2913 -+ CUR.error = TT_Err_Invalid_Reference;
2914 -+ goto Fail;
2915 -+ }
2916 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2917 - if ( CUR.top < CUR.GS.loop ||
2918 - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
2919 - {
2920 -@@ -6846,6 +7332,15 @@
2921 - contour = 0;
2922 - point = 0;
2923 -
2924 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2925 -+ if ( CUR.ignore_x_mode )
2926 -+ {
2927 -+ CUR.iup_called = 1;
2928 -+ if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
2929 -+ return;
2930 -+ }
2931 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2932 -+
2933 - do
2934 - {
2935 - end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
2936 -@@ -6915,7 +7410,9 @@
2937 - FT_UShort A;
2938 - FT_ULong C;
2939 - FT_Long B;
2940 --
2941 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2942 -+ FT_UShort B1, B2;
2943 -+#endif
2944 -
2945 - #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2946 - /* Delta hinting is covered by US Patent 5159668. */
2947 -@@ -6988,7 +7485,67 @@
2948 - B++;
2949 - B = B * 64 / ( 1L << CUR.GS.delta_shift );
2950 -
2951 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2952 -+ /*
2953 -+ * Allow delta move if
2954 -+ *
2955 -+ * - not using ignore_x_mode rendering
2956 -+ * - glyph is specifically set to allow it
2957 -+ * - glyph is composite and freedom vector is not subpixel vector
2958 -+ */
2959 -+ if ( !CUR.ignore_x_mode ||
2960 -+ ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
2961 -+ ( CUR.is_composite && CUR.GS.freeVector.y != 0 ))
2962 -+ CUR_Func_move( &CUR.zp0, A, B );
2963 -+
2964 -+ /* Otherwise apply subpixel hinting and compatibility mode rules */
2965 -+ else if ( CUR.ignore_x_mode )
2966 -+ {
2967 -+ if ( CUR.GS.freeVector.y != 0 )
2968 -+ B1 = CUR.zp0.cur[A].y;
2969 -+ else
2970 -+ B1 = CUR.zp0.cur[A].x;
2971 -+
2972 -+ /* Standard Subpixel Hinting: Allow y move */
2973 -+ if ( !CUR.compatibility_mode && CUR.GS.freeVector.y != 0 )
2974 -+ CUR_Func_move( &CUR.zp0, A, B );
2975 -+
2976 -+ /* Compatibility Mode: Allow x or y move if point touched in
2977 -+ Y direction */
2978 -+ else if ( CUR.compatibility_mode &&
2979 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ))
2980 -+ {
2981 -+ /* save the y value of the point now; compare after move */
2982 -+ B1 = CUR.zp0.cur[A].y;
2983 -+
2984 -+ if ( ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) )
2985 -+ B = FT_PIX_ROUND( B1 + B ) - B1;
2986 -+
2987 -+ /*
2988 -+ * Allow delta move if using compatibility_mode, IUP has not
2989 -+ * been called, and point is touched on Y.
2990 -+ */
2991 -+ if ( !CUR.iup_called &&
2992 -+ ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
2993 -+ CUR_Func_move( &CUR.zp0, A, B );
2994 -+ }
2995 -+ B2 = CUR.zp0.cur[A].y;
2996 -+
2997 -+ /* Reverse this move if it results in a disallowed move */
2998 -+ if ( CUR.GS.freeVector.y != 0 &&
2999 -+ ( ( ( CUR.sph_tweak_flags &
3000 -+ SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES ) &&
3001 -+ B1 % 64 == 0 &&
3002 -+ B2 % 64 != 0 ) ||
3003 -+ ( ( CUR.sph_tweak_flags &
3004 -+ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
3005 -+ B1 % 64 != 0 &&
3006 -+ B2 % 64 != 0 )))
3007 -+ CUR_Func_move( &CUR.zp0, A, -B );
3008 -+ }
3009 -+#else
3010 - CUR_Func_move( &CUR.zp0, A, B );
3011 -+#endif /* *TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3012 - }
3013 - }
3014 - else
3015 -@@ -7114,26 +7671,116 @@
3016 - Ins_GETINFO( INS_ARG )
3017 - {
3018 - FT_Long K;
3019 --
3020 --
3021 - K = 0;
3022 -
3023 -- /* We return MS rasterizer version 1.7 for the font scaler. */
3024 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3025 -+ /********************************/
3026 -+ /* RASTERIZER VERSION */
3027 -+ /* Selector Bit: 0 */
3028 -+ /* Return Bit(s): 0-7 */
3029 -+ /* */
3030 -+ if ( ( args[0] & 1 ) != 0 && CUR.ignore_x_mode )
3031 -+ {
3032 -+ K = CUR.rasterizer_version;
3033 -+#ifdef SPH_DEBUG_MORE_VERBOSE
3034 -+ printf(" SETTING AS %d\n", CUR.rasterizer_version );
3035 -+#endif
3036 -+ }
3037 -+ else
3038 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3039 - if ( ( args[0] & 1 ) != 0 )
3040 - K = 35;
3041 -
3042 -- /* Has the glyph been rotated? */
3043 -+ /********************************/
3044 -+ /* GLYPH ROTATED */
3045 -+ /* Selector Bit: 1 */
3046 -+ /* Return Bit(s): 8 */
3047 -+ /* */
3048 - if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
3049 - K |= 0x80;
3050 -
3051 -- /* Has the glyph been stretched? */
3052 -+ /********************************/
3053 -+ /* GLYPH STRETCHED */
3054 -+ /* Selector Bit: 2 */
3055 -+ /* Return Bit(s): 9 */
3056 -+ /* */
3057 - if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
3058 - K |= 1 << 8;
3059 -
3060 -- /* Are we hinting for grayscale? */
3061 -+ /********************************/
3062 -+ /* HINTING FOR GRAYSCALE */
3063 -+ /* Selector Bit: 5 */
3064 -+ /* Return Bit(s): 12 */
3065 -+ /* */
3066 - if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
3067 - K |= 1 << 12;
3068 -
3069 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3070 -+ if ( CUR.ignore_x_mode && CUR.rasterizer_version >= 35 )
3071 -+ {
3072 -+ /********************************/
3073 -+ /* HINTING FOR GRAYSCALE */
3074 -+ /* Selector Bit: 5 */
3075 -+ /* Return Bit(s): 12 */
3076 -+ /* */
3077 -+ if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting )
3078 -+ K |= 1 << 12;
3079 -+
3080 -+ /********************************/
3081 -+ /* HINTING FOR SUBPIXEL */
3082 -+ /* Selector Bit: 6 */
3083 -+ /* Return Bit(s): 13 */
3084 -+ /* */
3085 -+ if ( ( args[0] & 64 ) != 0 &&
3086 -+ CUR.subpixel_hinting &&
3087 -+ CUR.rasterizer_version >= 37 )
3088 -+ {
3089 -+ K |= 1 << 13;
3090 -+
3091 -+ /* the stuff below is irrelevant if subpixel_hinting is not set */
3092 -+
3093 -+ /********************************/
3094 -+ /* COMPATIBLE WIDTHS ENABLED */
3095 -+ /* Selector Bit: 7 */
3096 -+ /* Return Bit(s): 14 */
3097 -+ /* */
3098 -+ /* Functionality still needs to be added */
3099 -+ if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
3100 -+ K |= 1 << 14;
3101 -+
3102 -+ /********************************/
3103 -+ /* SYMMETRICAL SMOOTHING */
3104 -+ /* Selector Bit: 8 */
3105 -+ /* Return Bit(s): 15 */
3106 -+ /* */
3107 -+ /* Functionality still needs to be added */
3108 -+ if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing )
3109 -+ K |= 1 << 15;
3110 -+
3111 -+ /********************************/
3112 -+ /* HINTING FOR BGR? */
3113 -+ /* Selector Bit: 9 */
3114 -+ /* Return Bit(s): 16 */
3115 -+ /* */
3116 -+ /* Functionality still needs to be added */
3117 -+ if ( ( args[0] & 512 ) != 0 && CUR.bgr )
3118 -+ K |= 1 << 16;
3119 -+
3120 -+ if ( CUR.rasterizer_version >= 38 )
3121 -+ {
3122 -+
3123 -+ /********************************/
3124 -+ /* SUBPIXEL POSITIONED? */
3125 -+ /* Selector Bit: 10 */
3126 -+ /* Return Bit(s): 17 */
3127 -+ /* */
3128 -+ /* Functionality still needs to be added */
3129 -+ if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned )
3130 -+ K |= 1 << 17;
3131 -+ }
3132 -+ }
3133 -+ }
3134 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3135 - args[0] = K;
3136 - }
3137 -
3138 -@@ -7509,6 +8156,15 @@
3139 - cur = *exc;
3140 - #endif
3141 -
3142 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3143 -+ if ( CUR.ignore_x_mode )
3144 -+ {
3145 -+ /* ensure some variables are set for this run */
3146 -+ CUR.iup_called = FALSE;
3147 -+ CUR.in_delta_function = FALSE;
3148 -+ }
3149 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3150 -+
3151 - /* set CVT functions */
3152 - CUR.tt_metrics.ratio = 0;
3153 - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
3154 -@@ -7780,7 +8436,13 @@
3155 - break;
3156 -
3157 - case 0x2B: /* CALL */
3158 -- Ins_CALL( EXEC_ARG_ args );
3159 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3160 -+ if ( !CUR.ignore_x_mode ||
3161 -+ !CUR.iup_called ||
3162 -+ ( CUR.iup_called &&
3163 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) )
3164 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3165 -+ Ins_CALL( EXEC_ARG_ args );
3166 - break;
3167 -
3168 - case 0x2C: /* FDEF */
3169 -@@ -7799,6 +8461,9 @@
3170 -
3171 - case 0x30: /* IUP */
3172 - case 0x31: /* IUP */
3173 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3174 -+ if ( CUR.ignore_x_mode ) CUR.iup_called = TRUE;
3175 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3176 - Ins_IUP( EXEC_ARG_ args );
3177 - break;
3178 -
3179 -@@ -7958,6 +8623,12 @@
3180 - break;
3181 -
3182 - case 0x5D: /* DELTAP1 */
3183 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3184 -+ if ( !CUR.ignore_x_mode ||
3185 -+ !CUR.iup_called ||
3186 -+ ( CUR.iup_called &&
3187 -+ !( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) )
3188 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3189 - Ins_DELTAP( EXEC_ARG_ args );
3190 - break;
3191 -
3192 -diff -Nur freetype-orig/src/truetype/ttinterp.h freetype-subpixel/src/truetype/ttinterp.h
3193 ---- freetype-orig/src/truetype/ttinterp.h 2012-06-14 00:35:58.000000000 -0500
3194 -+++ freetype-subpixel/src/truetype/ttinterp.h 2012-06-16 10:31:58.279833085 -0500
3195 -@@ -68,7 +68,8 @@
3196 - /* Rounding function */
3197 - typedef FT_F26Dot6
3198 - (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance,
3199 -- FT_F26Dot6 compensation );
3200 -+ FT_F26Dot6 compensation,
3201 -+ FT_Int resolution );
3202 -
3203 - /* Point displacement along the freedom vector routine */
3204 - typedef void
3205 -@@ -107,6 +108,44 @@
3206 - } TT_CallRec, *TT_CallStack;
3207 -
3208 -
3209 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3210 -+
3211 -+ /*************************************************************************/
3212 -+ /* */
3213 -+ /* This structure defines a rule used to tweak subpixel hinting for */
3214 -+ /* various fonts. "", 0, "", NULL value indicates to match any value. */
3215 -+ /* */
3216 -+
3217 -+ typedef struct SPH_TweakRule_
3218 -+ {
3219 -+ const char family[32];
3220 -+ const int ppem;
3221 -+ const char style[32];
3222 -+ const FT_ULong glyph;
3223 -+
3224 -+ } SPH_TweakRule;
3225 -+
3226 -+
3227 -+ typedef struct SPH_ScaleRule_
3228 -+ {
3229 -+ const char family[32];
3230 -+ const int ppem;
3231 -+ const char style[32];
3232 -+ const FT_ULong glyph;
3233 -+ const float scale;
3234 -+ } SPH_ScaleRule;
3235 -+
3236 -+#define MAX_CLASS_MEMBERS 100
3237 -+
3238 -+ typedef struct Font_Class_
3239 -+ {
3240 -+ const char name[32];
3241 -+ const char member[MAX_CLASS_MEMBERS][32];
3242 -+ } Font_Class;
3243 -+
3244 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3245 -+
3246 -+
3247 - /*************************************************************************/
3248 - /* */
3249 - /* The main structure for the interpreter which collects all necessary */
3250 -@@ -218,6 +257,37 @@
3251 -
3252 - FT_Bool grayscale; /* are we hinting for grayscale? */
3253 -
3254 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3255 -+ TT_Round_Func func_round_sphn; /* subpixel rounding function */
3256 -+
3257 -+ FT_Bool grayscale_hinting; /* Using grayscale hinting? */
3258 -+ FT_Bool subpixel_hinting; /* Using subpixel hinting? */
3259 -+ FT_Bool native_hinting; /* Using native hinting? */
3260 -+ FT_Bool ignore_x_mode; /* Standard rendering mode for */
3261 -+ /* subpixel hinting. On if gray */
3262 -+ /* or subpixel hinting is on ) */
3263 -+ FT_Bool compatibility_mode;/* Additional exceptions to */
3264 -+ /* native TT rules for legacy */
3265 -+ /* fonts. Implies ignore_x_mode. */
3266 -+
3267 -+ /* The following 3 aren't fully implemented but here for MS rasterizer */
3268 -+ /* compatibility. */
3269 -+ FT_Bool compatible_widths; /* compatible widths? */
3270 -+ FT_Bool symmetrical_smoothing;/* symmetrical_smoothing? */
3271 -+ FT_Bool bgr; /* bgr instead of rgb? */
3272 -+ FT_Bool subpixel_positioned; /* MS DW subpixel positioned */
3273 -+
3274 -+ FT_Int rasterizer_version; /* MS rasterizer version */
3275 -+
3276 -+ FT_Bool iup_called; /* IUP called for glyph? */
3277 -+ FT_Bool in_delta_function; /* inside an inline delta func? */
3278 -+
3279 -+ FT_ULong sph_tweak_flags; /* flags to control hint tweaks */
3280 -+
3281 -+ FT_Int num_delta_funcs;
3282 -+ FT_ULong inline_delta_funcs[5];
3283 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3284 -+
3285 - } TT_ExecContextRec;
3286 -
3287 -
3288 -diff -Nur freetype-orig/src/truetype/ttobjs.h freetype-subpixel/src/truetype/ttobjs.h
3289 ---- freetype-orig/src/truetype/ttobjs.h 2012-06-14 00:35:58.000000000 -0500
3290 -+++ freetype-subpixel/src/truetype/ttobjs.h 2012-06-15 07:31:12.163985155 -0500
3291 -@@ -178,6 +178,7 @@
3292 - FT_Long end; /* where does it end? */
3293 - FT_UInt opc; /* function #, or instruction code */
3294 - FT_Bool active; /* is it active? */
3295 -+ FT_Bool inline_delta; /* is function that defines inline delta? */
3296 -
3297 - } TT_DefRecord, *TT_DefArray;
3298 -
3299 -@@ -190,7 +191,7 @@
3300 - {
3301 - FT_Fixed xx, xy; /* transformation matrix coefficients */
3302 - FT_Fixed yx, yy;
3303 -- FT_F26Dot6 ox, oy; /* offsets */
3304 -+ FT_F26Dot6 ox, oy; /* offsets */
3305 -
3306 - } TT_Transform;
3307 -
3308 -diff -Nur freetype-orig/src/truetype/ttsubpix.c freetype-subpixel/src/truetype/ttsubpix.c
3309 ---- freetype-orig/src/truetype/ttsubpix.c 1969-12-31 18:00:00.000000000 -0600
3310 -+++ freetype-subpixel/src/truetype/ttsubpix.c 2012-06-16 10:32:09.670447034 -0500
3311 -@@ -0,0 +1,261 @@
3312 -+/***************************************************************************/
3313 -+/* */
3314 -+/* ttsubpix.c */
3315 -+/* */
3316 -+/* TrueType Subpixel Hinting. */
3317 -+/* */
3318 -+/* Copyright 2010-2011 by */
3319 -+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
3320 -+/* */
3321 -+/* This file is part of the FreeType project, and may only be used, */
3322 -+/* modified, and distributed under the terms of the FreeType project */
3323 -+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
3324 -+/* this file you indicate that you have read the license and */
3325 -+/* understand and accept it fully. */
3326 -+/* */
3327 -+/***************************************************************************/
3328 -+
3329 -+#include <ft2build.h>
3330 -+#include FT_INTERNAL_DEBUG_H
3331 -+#include FT_INTERNAL_CALC_H
3332 -+#include FT_INTERNAL_STREAM_H
3333 -+#include FT_INTERNAL_SFNT_H
3334 -+#include FT_TRUETYPE_TAGS_H
3335 -+#include FT_OUTLINE_H
3336 -+
3337 -+#include "ttsubpix.h"
3338 -+
3339 -+
3340 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3341 -+
3342 -+ FT_LOCAL_DEF( FT_Bool )
3343 -+ is_member_of_family_class( const FT_String* detected_font_name,
3344 -+ const FT_String* rule_font_name )
3345 -+ {
3346 -+ FT_UInt i, j;
3347 -+
3348 -+ /* If font name matches rule family */
3349 -+ if ( strcmp( detected_font_name, rule_font_name ) == 0 ) return TRUE;
3350 -+
3351 -+ /* If font name is a wildcard "" */
3352 -+ if ( strcmp( rule_font_name, "" ) == 0 ) return TRUE;
3353 -+
3354 -+ /* If font name is contained in a class list */
3355 -+ for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ )
3356 -+ {
3357 -+ if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 )
3358 -+ {
3359 -+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ )
3360 -+ {
3361 -+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 )
3362 -+ continue;
3363 -+ if ( strcmp( FAMILY_CLASS_Rules[i].member[j], detected_font_name ) == 0 )
3364 -+ return TRUE;
3365 -+ }
3366 -+ }
3367 -+ }
3368 -+ return FALSE;
3369 -+ }
3370 -+
3371 -+
3372 -+ FT_LOCAL_DEF( FT_Bool )
3373 -+ is_member_of_style_class( const FT_String* detected_font_style,
3374 -+ const FT_String* rule_font_style )
3375 -+ {
3376 -+ FT_UInt i, j;
3377 -+
3378 -+ /* If font style matches rule style */
3379 -+ if ( strcmp( detected_font_style, rule_font_style ) == 0 ) return TRUE;
3380 -+
3381 -+ /* If font style is a wildcard "" */
3382 -+ if ( strcmp( rule_font_style, "" ) == 0 ) return TRUE;
3383 -+
3384 -+ /* If font style is contained in a class list */
3385 -+ for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ )
3386 -+ {
3387 -+ if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 )
3388 -+ {
3389 -+ for ( j = 0; j < MAX_CLASS_MEMBERS; j++ )
3390 -+ {
3391 -+ if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 )
3392 -+ continue;
3393 -+ if ( strcmp( STYLE_CLASS_Rules[i].member[j], detected_font_style ) == 0 )
3394 -+ return TRUE;
3395 -+ }
3396 -+ }
3397 -+ }
3398 -+ return FALSE;
3399 -+ }
3400 -+
3401 -+
3402 -+ FT_LOCAL_DEF( FT_Bool )
3403 -+ sph_test_tweak( TT_Face face,
3404 -+ FT_String* family,
3405 -+ int ppem,
3406 -+ FT_String* style,
3407 -+ FT_UInt glyph_index,
3408 -+ SPH_TweakRule* rule,
3409 -+ FT_UInt num_rules )
3410 -+ {
3411 -+ FT_UInt i;
3412 -+
3413 -+
3414 -+ /* rule checks may be able to be optimized further */
3415 -+ for ( i = 0; i < num_rules; i++ )
3416 -+ {
3417 -+ if ( family &&
3418 -+ ( is_member_of_family_class ( family, rule[i].family ) ) )
3419 -+ if ( rule[i].ppem == 0 ||
3420 -+ rule[i].ppem == ppem )
3421 -+ if ( style &&
3422 -+ is_member_of_style_class ( style, rule[i].style ) )
3423 -+ if ( rule[i].glyph == 0 ||
3424 -+ FT_Get_Char_Index( (FT_Face)face,
3425 -+ rule[i].glyph ) == glyph_index )
3426 -+ return TRUE;
3427 -+ }
3428 -+ return FALSE;
3429 -+ }
3430 -+
3431 -+
3432 -+ FT_LOCAL_DEF( float )
3433 -+ scale_test_tweak( TT_Face face,
3434 -+ FT_String* family,
3435 -+ int ppem,
3436 -+ FT_String* style,
3437 -+ FT_UInt glyph_index,
3438 -+ SPH_ScaleRule* rule,
3439 -+ FT_UInt num_rules )
3440 -+ {
3441 -+ FT_UInt i;
3442 -+
3443 -+
3444 -+ /* rule checks may be able to be optimized further */
3445 -+ for ( i = 0; i < num_rules; i++ )
3446 -+ {
3447 -+ if ( family &&
3448 -+ ( is_member_of_family_class ( family, rule[i].family ) ) )
3449 -+ if ( rule[i].ppem == 0 ||
3450 -+ rule[i].ppem == ppem )
3451 -+ if ( style &&
3452 -+ is_member_of_style_class( style, rule[i].style ) )
3453 -+ if ( rule[i].glyph == 0 ||
3454 -+ FT_Get_Char_Index( (FT_Face)face,
3455 -+ rule[i].glyph ) == glyph_index )
3456 -+ return rule[i].scale;
3457 -+ }
3458 -+ return 1.0;
3459 -+ }
3460 -+
3461 -+#define TWEAK_RULES( x ) \
3462 -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
3463 -+ x##_Rules, x##_RULES_SIZE ) ) \
3464 -+ loader->exec->sph_tweak_flags |= SPH_TWEAK_##x;
3465 -+
3466 -+#define TWEAK_RULES_EXCEPTIONS( x ) \
3467 -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index, \
3468 -+ x##_Rules_Exceptions, x##_RULES_EXCEPTIONS_SIZE ) ) \
3469 -+ loader->exec->sph_tweak_flags &= ~SPH_TWEAK_##x;
3470 -+
3471 -+ FT_LOCAL_DEF( void )
3472 -+ sph_set_tweaks( TT_Loader loader,
3473 -+ FT_UInt glyph_index )
3474 -+ {
3475 -+ TT_Face face = (TT_Face)loader->face;
3476 -+ FT_String* family = face->root.family_name;
3477 -+ int ppem = loader->size->metrics.x_ppem;
3478 -+ FT_String* style = face->root.style_name;
3479 -+
3480 -+ /* Don't apply rules if style isn't set */
3481 -+ if ( !face->root.style_name ) return;
3482 -+
3483 -+#ifdef SPH_DEBUG_MORE_VERBOSE
3484 -+ printf( "%s,%d,%s,%c=%d ", family, ppem, style, glyph_index, glyph_index );
3485 -+#endif
3486 -+
3487 -+ TWEAK_RULES( PIXEL_HINTING );
3488 -+
3489 -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_PIXEL_HINTING )
3490 -+ {
3491 -+ loader->exec->ignore_x_mode = FALSE;
3492 -+ return;
3493 -+ }
3494 -+
3495 -+ TWEAK_RULES( ALLOW_X_DMOVE );
3496 -+ TWEAK_RULES( ALLOW_X_DMOVEX );
3497 -+ TWEAK_RULES( ALLOW_X_MOVE_ZP2 );
3498 -+ TWEAK_RULES( ALWAYS_DO_DELTAP );
3499 -+ TWEAK_RULES( ALWAYS_SKIP_DELTAP );
3500 -+ TWEAK_RULES( DEEMBOLDEN );
3501 -+ TWEAK_RULES( DELTAP_SKIP_EXAGGERATED_VALUES );
3502 -+ TWEAK_RULES( DO_SHPIX );
3503 -+ TWEAK_RULES( EMBOLDEN );
3504 -+ TWEAK_RULES( MIAP_HACK );
3505 -+ TWEAK_RULES( NORMAL_ROUND );
3506 -+ TWEAK_RULES( NO_ALIGNRP_AFTER_IUP );
3507 -+ TWEAK_RULES( NO_CALL_AFTER_IUP );
3508 -+ TWEAK_RULES( NO_DELTAP_AFTER_IUP );
3509 -+ TWEAK_RULES( RASTERIZER_35 );
3510 -+ TWEAK_RULES( SKIP_INLINE_DELTAS );
3511 -+ TWEAK_RULES( SKIP_IUP );
3512 -+ TWEAK_RULES( MIRP_CVT_ZERO );
3513 -+
3514 -+ TWEAK_RULES( SKIP_OFFPIXEL_Y_MOVES );
3515 -+ TWEAK_RULES_EXCEPTIONS( SKIP_OFFPIXEL_Y_MOVES );
3516 -+
3517 -+ TWEAK_RULES( SKIP_NONPIXEL_Y_MOVES );
3518 -+ TWEAK_RULES_EXCEPTIONS( SKIP_NONPIXEL_Y_MOVES );
3519 -+
3520 -+ TWEAK_RULES( ROUND_NONPIXEL_Y_MOVES );
3521 -+ TWEAK_RULES_EXCEPTIONS( ROUND_NONPIXEL_Y_MOVES );
3522 -+
3523 -+ if ( loader->exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
3524 -+ {
3525 -+ if ( loader->exec->rasterizer_version != 35 )
3526 -+ {
3527 -+ loader->exec->rasterizer_version = 35;
3528 -+ /* must re-execute fpgm */
3529 -+ loader->exec->size->cvt_ready = FALSE;
3530 -+ tt_size_ready_bytecode( loader->exec->size,
3531 -+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
3532 -+ }
3533 -+ }
3534 -+ else
3535 -+ {
3536 -+ if ( loader->exec->rasterizer_version == 35 )
3537 -+ {
3538 -+ loader->exec->rasterizer_version = 37;
3539 -+ /* must re-execute fpgm */
3540 -+ loader->exec->size->cvt_ready = FALSE;
3541 -+ tt_size_ready_bytecode( loader->exec->size,
3542 -+ FT_BOOL( loader->load_flags & FT_LOAD_PEDANTIC ) );
3543 -+ }
3544 -+ }
3545 -+
3546 -+ if ( IS_HINTED( loader->load_flags ) )
3547 -+ {
3548 -+ TWEAK_RULES( TIMES_NEW_ROMAN_HACK );
3549 -+ TWEAK_RULES( COURIER_NEW_2_HACK );
3550 -+ }
3551 -+
3552 -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index,
3553 -+ COMPATIBILITY_MODE_Rules, COMPATIBILITY_MODE_RULES_SIZE ) )
3554 -+ {
3555 -+ loader->exec->compatibility_mode |= TRUE;
3556 -+ loader->exec->ignore_x_mode |= TRUE;
3557 -+ }
3558 -+ else
3559 -+ loader->exec->compatibility_mode &= FALSE;
3560 -+
3561 -+ if ( IS_HINTED( loader->load_flags ) )
3562 -+ {
3563 -+ if ( sph_test_tweak( face, family, ppem, style, glyph_index,
3564 -+ COMPATIBLE_WIDTHS_Rules, COMPATIBLE_WIDTHS_RULES_SIZE ) )
3565 -+ loader->exec->compatible_widths |= TRUE;
3566 -+ }
3567 -+ }
3568 -+
3569 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
3570 -+
3571 -+
3572 -+/* END */
3573 -diff -Nur freetype-orig/src/truetype/ttsubpix.h freetype-subpixel/src/truetype/ttsubpix.h
3574 ---- freetype-orig/src/truetype/ttsubpix.h 1969-12-31 18:00:00.000000000 -0600
3575 -+++ freetype-subpixel/src/truetype/ttsubpix.h 2012-06-16 10:30:26.121956142 -0500
3576 -@@ -0,0 +1,778 @@
3577 -+/***************************************************************************/
3578 -+/* */
3579 -+/* ttsubpix.h */
3580 -+/* */
3581 -+/* TrueType Subpixel Hinting. */
3582 -+/* */
3583 -+/* Copyright 2010-2011 by */
3584 -+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
3585 -+/* */
3586 -+/* This file is part of the FreeType project, and may only be used, */
3587 -+/* modified, and distributed under the terms of the FreeType project */
3588 -+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
3589 -+/* this file you indicate that you have read the license and */
3590 -+/* understand and accept it fully. */
3591 -+/* */
3592 -+/***************************************************************************/
3593 -+
3594 -+#ifndef __TTSUBPIX_H__
3595 -+#define __TTSUBPIX_H__
3596 -+
3597 -+#include <ft2build.h>
3598 -+#include "ttobjs.h"
3599 -+#include "ttinterp.h"
3600 -+
3601 -+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
3602 -+
3603 -+ /*************************************************************************/
3604 -+ /* */
3605 -+ /* Tweak flags that are set for each glyph by the below rules */
3606 -+ /* */
3607 -+ /* */
3608 -+#define SPH_TWEAK_ALLOW_X_DMOVE 0x0000001
3609 -+#define SPH_TWEAK_ALLOW_X_DMOVEX 0x0000002
3610 -+#define SPH_TWEAK_ALLOW_X_MOVE_ZP2 0x0000004
3611 -+#define SPH_TWEAK_ALWAYS_DO_DELTAP 0x0000008
3612 -+#define SPH_TWEAK_ALWAYS_SKIP_DELTAP 0x0000010
3613 -+#define SPH_TWEAK_COURIER_NEW_2_HACK 0x0000020
3614 -+#define SPH_TWEAK_DEEMBOLDEN 0x0000040
3615 -+#define SPH_TWEAK_DELTAP_SKIP_EXAGGERATED_VALUES 0x0000080
3616 -+#define SPH_TWEAK_DO_SHPIX 0x0000100
3617 -+#define SPH_TWEAK_EMBOLDEN 0x0000200
3618 -+#define SPH_TWEAK_MIAP_HACK 0x0000400
3619 -+#define SPH_TWEAK_NORMAL_ROUND 0x0000800
3620 -+#define SPH_TWEAK_NO_ALIGNRP_AFTER_IUP 0x0001000
3621 -+#define SPH_TWEAK_NO_CALL_AFTER_IUP 0x0002000
3622 -+#define SPH_TWEAK_NO_DELTAP_AFTER_IUP 0x0004000
3623 -+#define SPH_TWEAK_PIXEL_HINTING 0x0008000
3624 -+#define SPH_TWEAK_RASTERIZER_35 0x0010000
3625 -+#define SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES 0x0020000
3626 -+#define SPH_TWEAK_SKIP_INLINE_DELTAS 0x0040000
3627 -+#define SPH_TWEAK_SKIP_IUP 0x0080000
3628 -+#define SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES 0x0100000
3629 -+#define SPH_TWEAK_SKIP_OFFPIXEL_Y_MOVES 0x0200000
3630 -+#define SPH_TWEAK_TIMES_NEW_ROMAN_HACK 0x0400000
3631 -+#define SPH_TWEAK_MIRP_CVT_ZERO 0x0800000
3632 -+
3633 -+
3634 -+ FT_LOCAL( FT_Bool )
3635 -+ sph_test_tweak( TT_Face face,
3636 -+ FT_String* family,
3637 -+ int ppem,
3638 -+ FT_String* style,
3639 -+ FT_UInt glyph_index,
3640 -+ SPH_TweakRule* rule,
3641 -+ FT_UInt num_rules );
3642 -+
3643 -+ FT_LOCAL_DEF( float )
3644 -+ scale_test_tweak( TT_Face face,
3645 -+ FT_String* family,
3646 -+ int ppem,
3647 -+ FT_String* style,
3648 -+ FT_UInt glyph_index,
3649 -+ SPH_ScaleRule* rule,
3650 -+ FT_UInt num_rules );
3651 -+
3652 -+ FT_LOCAL( void )
3653 -+ sph_set_tweaks( TT_Loader loader,
3654 -+ FT_UInt glyph_index );
3655 -+
3656 -+
3657 -+ /*************************************************************************/
3658 -+ /* */
3659 -+ /* These rules affect how the TT Interpreter does hinting, with the */
3660 -+ /* goal of doing subpixel hinting by (in general) ignoring x moves. */
3661 -+ /* Some of these rules are fixes that go above and beyond the */
3662 -+ /* stated techniques in the MS whitepaper on Cleartype, due to */
3663 -+ /* artifacts in many glyphs. So, these rules make some glyphs render */
3664 -+ /* better than they do in the MS rasterizer. */
3665 -+ /* */
3666 -+ /* "" string or 0 int/char indicates to apply to all glyphs. */
3667 -+ /* "-" used as dummy placeholders, but any non-matching string works. */
3668 -+ /* */
3669 -+ /* Some of this could arguably be implemented in fontconfig, however: */
3670 -+ /* */
3671 -+ /* - Fontconfig can't set things on a glyph-by-glyph basis. */
3672 -+ /* - The tweaks that happen here are very low-level, from an average */
3673 -+ /* user's point of view and are best implemented in the hinter */
3674 -+ /* */
3675 -+ /* The goal is to make the subpixel hinting techniques as generalized */
3676 -+ /* as possible across all fonts to prevent the need for extra rules such */
3677 -+ /* as these. */
3678 -+ /* */
3679 -+ /* The rule structure is designed so that entirely new rules can easily */
3680 -+ /* be added when a new compatibility feature is discovered. */
3681 -+ /* */
3682 -+ /* The rule structures could also use some enhancement to handle ranges. */
3683 -+ /* */
3684 -+ /* ****************** WORK IN PROGRESS ******************* */
3685 -+ /* */
3686 -+
3687 -+#define SPH_OPTION_BITMAP_WIDTHS FALSE
3688 -+#define SPH_OPTION_SET_SUBPIXEL TRUE
3689 -+#define SPH_OPTION_SET_GRAYSCALE FALSE
3690 -+#define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE
3691 -+#define SPH_OPTION_SET_RASTERIZER_VERSION 37
3692 -+#define SPH_OPTION_GRIDLINES_PER_PIXEL_X 64
3693 -+#define SPH_OPTION_GRIDLINES_PER_PIXEL_Y 1
3694 -+
3695 -+#define MAX_CLASS_MEMBERS 100
3696 -+
3697 -+/* Define this to force natural (i.e. not bitmap-compatible) widths. */
3698 -+/* The default leans strongly towards natural widths except for a few */
3699 -+/* legacy fonts where a selective combination produces nicer results. */
3700 -+/* #define FORCE_NATURAL_WIDTHS */
3701 -+
3702 -+
3703 -+ /* These are "classes" of fonts that can be grouped together and used in */
3704 -+ /* rules below. A blank entry "" is required at the end of these! */
3705 -+#define FAMILY_CLASS_RULES_SIZE 7
3706 -+ Font_Class FAMILY_CLASS_Rules
3707 -+ [FAMILY_CLASS_RULES_SIZE] =
3708 -+ {
3709 -+ { "MS Legacy Fonts", { "Aharoni",
3710 -+ "Andale Mono",
3711 -+ "Andalus",
3712 -+ "Angsana New",
3713 -+ "AngsanaUPC",
3714 -+ "Arabic Transparent",
3715 -+ "Arial Black",
3716 -+ "Arial Narrow",
3717 -+ "Arial Unicode MS",
3718 -+ "Arial",
3719 -+ "Batang",
3720 -+ "Browallia New",
3721 -+ "BrowalliaUPC",
3722 -+ "Comic Sans MS",
3723 -+ "Cordia New",
3724 -+ "CordiaUPC",
3725 -+ "Courier New",
3726 -+ "DFKai-SB",
3727 -+ "David Transparent",
3728 -+ "David",
3729 -+ "DilleniaUPC",
3730 -+ "Estrangelo Edessa",
3731 -+ "EucrosiaUPC",
3732 -+ "FangSong_GB2312",
3733 -+ "Fixed Miriam Transparent",
3734 -+ "FrankRuehl",
3735 -+ "Franklin Gothic Medium",
3736 -+ "FreesiaUPC",
3737 -+ "Garamond",
3738 -+ "Gautami",
3739 -+ "Georgia",
3740 -+ "Gulim",
3741 -+ "Impact",
3742 -+ "IrisUPC",
3743 -+ "JasmineUPC",
3744 -+ "KaiTi_GB2312",
3745 -+ "KodchiangUPC",
3746 -+ "Latha",
3747 -+ "Levenim MT",
3748 -+ "LilyUPC",
3749 -+ "Lucida Console",
3750 -+ "Lucida Sans Unicode",
3751 -+ "MS Gothic",
3752 -+ "MS Mincho",
3753 -+ "MV Boli",
3754 -+ "Mangal",
3755 -+ "Marlett",
3756 -+ "Microsoft Sans Serif",
3757 -+ "Mingliu",
3758 -+ "Miriam Fixed",
3759 -+ "Miriam Transparent",
3760 -+ "Miriam",
3761 -+ "Narkisim",
3762 -+ "Palatino Linotype",
3763 -+ "Raavi",
3764 -+ "Rod Transparent",
3765 -+ "Rod",
3766 -+ "Shruti",
3767 -+ "SimHei",
3768 -+ "Simplified Arabic Fixed",
3769 -+ "Simplified Arabic",
3770 -+ "Simsun",
3771 -+ "Sylfaen",
3772 -+ "Symbol",
3773 -+ "Tahoma",
3774 -+ "Times New Roman",
3775 -+ "Traditional Arabic",
3776 -+ "Trebuchet MS",
3777 -+ "Tunga",
3778 -+ "Verdana",
3779 -+ "Webdings",
3780 -+ "Wingdings", "", }, },
3781 -+ { "Core MS Legacy Fonts", { "Arial Black",
3782 -+ "Arial Narrow",
3783 -+ "Arial Unicode MS",
3784 -+ "Arial",
3785 -+ "Comic Sans MS",
3786 -+ "Courier New",
3787 -+ "Garamond",
3788 -+ "Georgia",
3789 -+ "Impact",
3790 -+ "Lucida Console",
3791 -+ "Lucida Sans Unicode",
3792 -+ "Microsoft Sans Serif",
3793 -+ "Palatino Linotype",
3794 -+ "Tahoma",
3795 -+ "Times New Roman",
3796 -+ "Trebuchet MS",
3797 -+ "Verdana", "", }, },
3798 -+ { "Apple Legacy Fonts", { "Geneva",
3799 -+ "Times",
3800 -+ "Monaco",
3801 -+ "Century",
3802 -+ "Chalkboard",
3803 -+ "Lobster",
3804 -+ "Century Gothic",
3805 -+ "Optima",
3806 -+ "Lucida Grande",
3807 -+ "Gill Sans",
3808 -+ "Baskerville",
3809 -+ "Helvetica",
3810 -+ "Helvetica Neue", "", }, },
3811 -+ { "Legacy Sans Fonts", { "Andale Mono",
3812 -+ "Arial Unicode MS",
3813 -+ "Arial",
3814 -+ "Century Gothic",
3815 -+ "Comic Sans MS",
3816 -+ "Franklin Gothic Medium",
3817 -+ "Geneva",
3818 -+ "Lucida Console",
3819 -+ "Lucida Grande",
3820 -+ "Lucida Sans Unicode",
3821 -+ "Microsoft Sans Serif",
3822 -+ "Monaco",
3823 -+ "Tahoma",
3824 -+ "Trebuchet MS",
3825 -+ "Verdana", "", }, },
3826 -+ { "Misc Legacy Fonts", { "Dark Courier", "", }, },
3827 -+ { "Verdana Clones", { "DejaVu Sans",
3828 -+ "Bitstream Vera Sans", "", }, },
3829 -+ { "Verdana and Clones", { "DejaVu Sans",
3830 -+ "Bitstream Vera Sans",
3831 -+ "Verdana", "", }, },
3832 -+};
3833 -+
3834 -+
3835 -+ /* Define "classes" of styles that can be grouped together and used in */
3836 -+ /* rules below. A blank entry "" is required at the end of these! */
3837 -+#define STYLE_CLASS_RULES_SIZE 5
3838 -+ Font_Class STYLE_CLASS_Rules
3839 -+ [STYLE_CLASS_RULES_SIZE] =
3840 -+ {
3841 -+ { "Regular Class", { "Regular",
3842 -+ "Book",
3843 -+ "Medium",
3844 -+ "Roman",
3845 -+ "Normal", "", }, },
3846 -+ { "Regular/Italic Class", { "Regular",
3847 -+ "Book",
3848 -+ "Medium",
3849 -+ "Italic",
3850 -+ "Oblique",
3851 -+ "Roman",
3852 -+ "Normal", "", }, },
3853 -+ { "Bold/BoldItalic Class", { "Bold",
3854 -+ "Bold Italic",
3855 -+ "Black", "", }, },
3856 -+ { "Bold/Italic/BoldItalic Class", { "Bold",
3857 -+ "Bold Italic",
3858 -+ "Black",
3859 -+ "Italic",
3860 -+ "Oblique", "", }, },
3861 -+ { "Regular/Bold Class", { "Regular",
3862 -+ "Book",
3863 -+ "Medium",
3864 -+ "Normal",
3865 -+ "Roman",
3866 -+ "Bold",
3867 -+ "Black", "", }, },
3868 -+ };
3869 -+
3870 -+
3871 -+
3872 -+ /* Special fixes for known legacy fonts */
3873 -+ /* This is the primary workhorse rule for legacy fonts */
3874 -+#define COMPATIBILITY_MODE_RULES_SIZE 4
3875 -+ SPH_TweakRule COMPATIBILITY_MODE_Rules
3876 -+ [COMPATIBILITY_MODE_RULES_SIZE] =
3877 -+ {
3878 -+ { "MS Legacy Fonts", 0, "", 0 },
3879 -+ { "Apple Legacy Fonts", 0, "", 0 },
3880 -+ { "Misc Legacy Fonts", 0, "", 0 },
3881 -+ { "Verdana Clones", 0, "", 0 },
3882 -+ };
3883 -+
3884 -+
3885 -+ /* Don't do subpixel (ignore_x_mode) hinting; do normal hinting */
3886 -+#define PIXEL_HINTING_RULES_SIZE 4
3887 -+ SPH_TweakRule PIXEL_HINTING_Rules
3888 -+ [PIXEL_HINTING_RULES_SIZE] =
3889 -+ {
3890 -+ /* These characters are almost always safe */
3891 -+ { "", 0, "", '<' },
3892 -+ { "", 0, "", '>' },
3893 -+ /* Fixes the vanishing stem */
3894 -+ { "Times New Roman", 0, "Bold", 'A' },
3895 -+ { "Times New Roman", 0, "Bold", 'V' },
3896 -+ };
3897 -+
3898 -+
3899 -+ /* According to Greg Hitchcock and the MS whitepaper, this should work */
3900 -+ /* on all legacy MS fonts, but creates artifacts with some. Only using */
3901 -+ /* where absolutely necessary. */
3902 -+#define SKIP_INLINE_DELTAS_RULES_SIZE 1
3903 -+ SPH_TweakRule SKIP_INLINE_DELTAS_Rules
3904 -+ [SKIP_INLINE_DELTAS_RULES_SIZE] =
3905 -+ {
3906 -+ { "-", 0, "", 0 },
3907 -+ };
3908 -+
3909 -+
3910 -+ /* Subpixel hinting ignores SHPIX rules on X. Force SHPIX for these. */
3911 -+#define DO_SHPIX_RULES_SIZE 1
3912 -+ SPH_TweakRule DO_SHPIX_Rules
3913 -+ [DO_SHPIX_RULES_SIZE] =
3914 -+ {
3915 -+ { "-", 0, "", 0 },
3916 -+ };
3917 -+
3918 -+
3919 -+ /* Skip Y moves that start with a point that is not on a Y pixel */
3920 -+ /* boundary and don't move that point to a Y pixel boundary. */
3921 -+#define SKIP_NONPIXEL_Y_MOVES_RULES_SIZE 8
3922 -+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules
3923 -+ [SKIP_NONPIXEL_Y_MOVES_RULES_SIZE] =
3924 -+ {
3925 -+ /* fix vwxyz thinness*/
3926 -+ { "Consolas", 0, "Regular", 0 },
3927 -+ /* fix tiny gap at top of m */
3928 -+ { "Arial", 0, "Regular", 'm' },
3929 -+ /* Fix thin middle stems */
3930 -+ { "Core MS Legacy Fonts", 0, "Regular/Bold Class", 'N' },
3931 -+ { "Lucida Grande", 0, "", 'N' },
3932 -+ { "Legacy Sans Fonts", 0, "", L'и' },
3933 -+ { "Verdana Clones", 0, "",'N' },
3934 -+ { "Ubuntu", 0, "Regular Class", 'N' },
3935 -+ /* Fix misshapen x */
3936 -+ { "Verdana", 0, "Bold", 'x' },
3937 -+ };
3938 -+
3939 -+#define SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 4
3940 -+ SPH_TweakRule SKIP_NONPIXEL_Y_MOVES_Rules_Exceptions
3941 -+ [SKIP_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
3942 -+ {
3943 -+ { "Tahoma", 0, "", 'N' },
3944 -+ { "Comic Sans MS", 0, "", 'N' },
3945 -+ { "Verdana", 0, "Regular/Bold Class", 'N' },
3946 -+ { "Verdana", 11, "Bold", 'x' },
3947 -+ };
3948 -+
3949 -+
3950 -+
3951 -+ /* Skip Y moves that move a point off a Y pixel boundary */
3952 -+ /* This fixes Tahoma, Trebuchet oddities and some issues with `$' */
3953 -+#define SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE 5
3954 -+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules
3955 -+ [SKIP_OFFPIXEL_Y_MOVES_RULES_SIZE] =
3956 -+ {
3957 -+ { "MS Legacy Fonts", 0, "", 0 },
3958 -+ { "Apple Legacy Fonts", 0, "", 0 },
3959 -+ { "Misc Legacy Fonts", 0, "", 0 },
3960 -+ { "Ubuntu", 0, "Regular Class", 0 },
3961 -+ { "Verdana Clones", 0, "", 0 },
3962 -+ };
3963 -+
3964 -+
3965 -+#define SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 1
3966 -+ SPH_TweakRule SKIP_OFFPIXEL_Y_MOVES_Rules_Exceptions
3967 -+ [SKIP_OFFPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
3968 -+ {
3969 -+ { "-", 0, "", 0 },
3970 -+ };
3971 -+
3972 -+
3973 -+ /* Round moves that don't move a point to a Y pixel boundary */
3974 -+#define ROUND_NONPIXEL_Y_MOVES_RULES_SIZE 3
3975 -+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules
3976 -+ [ROUND_NONPIXEL_Y_MOVES_RULES_SIZE] =
3977 -+ {
3978 -+ /* Droid font instructions don't snap Y to pixels */
3979 -+ { "Droid Sans", 0, "Regular/Italic Class", 0 },
3980 -+ { "Droid Sans Mono", 0, "", 0 },
3981 -+ { "Ubuntu", 0, "", 0 },
3982 -+ };
3983 -+
3984 -+#define ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE 3
3985 -+ SPH_TweakRule ROUND_NONPIXEL_Y_MOVES_Rules_Exceptions
3986 -+ [ROUND_NONPIXEL_Y_MOVES_RULES_EXCEPTIONS_SIZE] =
3987 -+ {
3988 -+ { "Droid Sans", 12, "Bold", 0 },
3989 -+ { "Droid Sans", 13, "Bold", 0 },
3990 -+ { "Droid Sans", 16, "Bold", 0 },
3991 -+ };
3992 -+
3993 -+ /* Allow a Direct_Move_X along X freedom vector if matched */
3994 -+#define ALLOW_X_DMOVEX_RULES_SIZE 2
3995 -+ SPH_TweakRule ALLOW_X_DMOVEX_Rules
3996 -+ [ALLOW_X_DMOVEX_RULES_SIZE] =
3997 -+ {
3998 -+ /* Creates a more consistent appearance for these */
3999 -+ { "Arial", 13, "Regular", 'e' },
4000 -+ { "Arial", 13, "Regular", 'o' },
4001 -+ };
4002 -+
4003 -+ /* Allow a Direct_Move along X freedom vector if matched */
4004 -+#define ALLOW_X_DMOVE_RULES_SIZE 3
4005 -+ SPH_TweakRule ALLOW_X_DMOVE_Rules
4006 -+ [ALLOW_X_DMOVE_RULES_SIZE] =
4007 -+ {
4008 -+ /* Creates a more consistent appearance for these */
4009 -+ { "Arial", 13, "Regular", 'e' },
4010 -+ { "Arial", 13, "Regular", 'o' },
4011 -+ /* Fixes vanishing diagonal in 4 */
4012 -+ { "Verdana", 0, "Regular", '4' },
4013 -+ };
4014 -+
4015 -+ /* Allow a ZP2 move along freedom vector if matched; */
4016 -+ /* This is called from SHP, SHPIX, SHC, SHZ */
4017 -+#define ALLOW_X_MOVE_ZP2_RULES_SIZE 1
4018 -+ SPH_TweakRule ALLOW_X_MOVE_ZP2_Rules
4019 -+ [ALLOW_X_MOVE_ZP2_RULES_SIZE] =
4020 -+ {
4021 -+ { "-", 0, "", 0 },
4022 -+ };
4023 -+
4024 -+ /* Return MS rasterizer version 35 if matched */
4025 -+#define RASTERIZER_35_RULES_SIZE 8
4026 -+ SPH_TweakRule RASTERIZER_35_Rules
4027 -+ [RASTERIZER_35_RULES_SIZE] =
4028 -+ {
4029 -+ /* This seems to be the only way to make these look good */
4030 -+ { "Times New Roman", 0, "Regular", 'i' },
4031 -+ { "Times New Roman", 0, "Regular", 'j' },
4032 -+ { "Times New Roman", 0, "Regular", 'm' },
4033 -+ { "Times New Roman", 0, "Regular", 'r' },
4034 -+ { "Times New Roman", 0, "Regular", 'a' },
4035 -+ { "Times New Roman", 0, "Regular", 'n' },
4036 -+ { "Times New Roman", 0, "Regular", 'p' },
4037 -+ { "Times", 0, "", 0 },
4038 -+ };
4039 -+
4040 -+ /* Don't round to the subpixel grid. Round to pixel grid. */
4041 -+#define NORMAL_ROUND_RULES_SIZE 2
4042 -+ SPH_TweakRule NORMAL_ROUND_Rules
4043 -+ [NORMAL_ROUND_RULES_SIZE] =
4044 -+ {
4045 -+ /* Fix point "explosions" */
4046 -+ { "Courier New", 0, "", 0 },
4047 -+ { "Verdana", 10, "Regular", '4' },
4048 -+ };
4049 -+
4050 -+ /* Skip IUP instructions if matched */
4051 -+#define SKIP_IUP_RULES_SIZE 1
4052 -+ SPH_TweakRule SKIP_IUP_Rules
4053 -+ [SKIP_IUP_RULES_SIZE] =
4054 -+ {
4055 -+ { "Arial", 13, "Regular", 'a' },
4056 -+ };
4057 -+
4058 -+ /* Skip MIAP Twilight hack if matched */
4059 -+#define MIAP_HACK_RULES_SIZE 1
4060 -+ SPH_TweakRule MIAP_HACK_Rules
4061 -+ [MIAP_HACK_RULES_SIZE] =
4062 -+ {
4063 -+ { "Geneva", 12, "", 0 },
4064 -+ };
4065 -+
4066 -+ /* Skip DELTAP instructions if matched */
4067 -+#define ALWAYS_SKIP_DELTAP_RULES_SIZE 13
4068 -+ SPH_TweakRule ALWAYS_SKIP_DELTAP_Rules
4069 -+ [ALWAYS_SKIP_DELTAP_RULES_SIZE] =
4070 -+ {
4071 -+ { "Georgia", 0, "Regular", 'k' },
4072 -+ /* fixes problems with W M w */
4073 -+ { "Trebuchet MS", 0, "Italic", 0 },
4074 -+ { "Trebuchet MS", 14, "Regular", 'e' },
4075 -+ { "Arial", 11, "Regular", 's' },
4076 -+ { "Verdana", 10, "Regular", 0 },
4077 -+ { "Verdana", 9, "Regular", 0 },
4078 -+ { "Legacy Sans Fonts", 0, "", L'й' },
4079 -+ { "Arial", 10, "Regular", '6' },
4080 -+ { "Arial", 0, "Bold/BoldItalic Class", 'a' },
4081 -+ /* Make horizontal stems consistent with the rest */
4082 -+ { "Arial", 24, "Bold", 's' },
4083 -+ { "Arial", 25, "Bold", 's' },
4084 -+ { "Arial", 24, "Bold", 'a' },
4085 -+ { "Arial", 25, "Bold", 'a' },
4086 -+ };
4087 -+
4088 -+ /* Always do DELTAP instructions if matched */
4089 -+#define ALWAYS_DO_DELTAP_RULES_SIZE 2
4090 -+ SPH_TweakRule ALWAYS_DO_DELTAP_Rules
4091 -+ [ALWAYS_DO_DELTAP_RULES_SIZE] =
4092 -+ {
4093 -+ { "Verdana Clones", 17, "Regular Class", 'K' },
4094 -+ { "Verdana Clones", 17, "Regular Class", 'k' },
4095 -+ };
4096 -+
4097 -+ /* Do an extra RTG instruction in DELTAP if matched */
4098 -+#define DELTAP_RTG_RULES_SIZE 1
4099 -+ SPH_TweakRule DELTAP_RTG_Rules
4100 -+ [DELTAP_RTG_RULES_SIZE] =
4101 -+ {
4102 -+ { "-", 0, "", 0 },
4103 -+ };
4104 -+
4105 -+ /* Force CVT distance to zero in MIRP */
4106 -+#define MIRP_CVT_ZERO_RULES_SIZE 1
4107 -+ SPH_TweakRule MIRP_CVT_ZERO_Rules
4108 -+ [MIRP_CVT_ZERO_RULES_SIZE] =
4109 -+ {
4110 -+ { "Verdana", 0, "Regular", 0 },
4111 -+ };
4112 -+
4113 -+ /* Skip moves that meet or exceed 1 pixel */
4114 -+#define DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE 2
4115 -+ SPH_TweakRule DELTAP_SKIP_EXAGGERATED_VALUES_Rules
4116 -+ [DELTAP_SKIP_EXAGGERATED_VALUES_RULES_SIZE] =
4117 -+ {
4118 -+ /* Fix vanishing stems */
4119 -+ { "Ubuntu", 0, "Regular", 'M' },
4120 -+ /* Fix X at larger ppems */
4121 -+ { "Segoe UI", 0, "Light", 0 },
4122 -+ };
4123 -+
4124 -+ /* Don't allow ALIGNRP after IUP */
4125 -+#define NO_ALIGNRP_AFTER_IUP_RULES_SIZE 4
4126 -+ SPH_TweakRule NO_ALIGNRP_AFTER_IUP_Rules
4127 -+ [NO_ALIGNRP_AFTER_IUP_RULES_SIZE] =
4128 -+ {
4129 -+ /* Prevent creation of dents in outline */
4130 -+ { "Courier New", 0, "Bold", 'C' },
4131 -+ { "Courier New", 0, "Bold", 'D' },
4132 -+ { "Courier New", 0, "Bold", 'Q' },
4133 -+ { "Courier New", 0, "Bold", '0' },
4134 -+ };
4135 -+
4136 -+ /* Don't allow DELTAP after IUP */
4137 -+#define NO_DELTAP_AFTER_IUP_RULES_SIZE 2
4138 -+ SPH_TweakRule NO_DELTAP_AFTER_IUP_Rules
4139 -+ [NO_DELTAP_AFTER_IUP_RULES_SIZE] =
4140 -+ {
4141 -+ { "Arial", 0, "Bold", 'N' },
4142 -+ { "Verdana", 0, "Regular", '4' },
4143 -+ };
4144 -+
4145 -+ /* Don't allow CALL after IUP */
4146 -+#define NO_CALL_AFTER_IUP_RULES_SIZE 4
4147 -+ SPH_TweakRule NO_CALL_AFTER_IUP_Rules
4148 -+ [NO_CALL_AFTER_IUP_RULES_SIZE] =
4149 -+ {
4150 -+ /* Prevent creation of dents in outline */
4151 -+ { "Courier New", 0, "Bold", 'O' },
4152 -+ { "Courier New", 0, "Bold", 'Q' },
4153 -+ { "Courier New", 0, "Bold", 'k' },
4154 -+ { "Courier New", 0, "Bold Italic", 'M' },
4155 -+ };
4156 -+
4157 -+ /* De-embolden these glyphs slightly */
4158 -+#define DEEMBOLDEN_RULES_SIZE 9
4159 -+ SPH_TweakRule DEEMBOLDEN_Rules
4160 -+ [DEEMBOLDEN_RULES_SIZE] =
4161 -+ {
4162 -+ { "Courier New", 0, "Bold", 'A' },
4163 -+ { "Courier New", 0, "Bold", 'W' },
4164 -+ { "Courier New", 0, "Bold", 'w' },
4165 -+ { "Courier New", 0, "Bold", 'M' },
4166 -+ { "Courier New", 0, "Bold", 'X' },
4167 -+ { "Courier New", 0, "Bold", 'K' },
4168 -+ { "Courier New", 0, "Bold", 'x' },
4169 -+ { "Courier New", 0, "Bold", 'z' },
4170 -+ { "Courier New", 0, "Bold", 'v' },
4171 -+ };
4172 -+
4173 -+ /* Embolden these glyphs slightly */
4174 -+#define EMBOLDEN_RULES_SIZE 5
4175 -+ SPH_TweakRule EMBOLDEN_Rules
4176 -+ [EMBOLDEN_RULES_SIZE] =
4177 -+ {
4178 -+ { "Courier New", 12, "Italic", 'z' },
4179 -+ { "Courier New", 11, "Italic", 'z' },
4180 -+ { "Courier New", 10, "Italic", 'z' },
4181 -+ { "Courier New", 0, "Regular", 0 },
4182 -+ { "Courier New", 0, "Italic", 0 },
4183 -+ };
4184 -+
4185 -+ /* Do an extra RDTG instruction in DELTAP if matched */
4186 -+#define DELTAP_RDTG_RULES_SIZE 1
4187 -+ SPH_TweakRule DELTAP_RDTG_Rules
4188 -+ [DELTAP_RDTG_RULES_SIZE] =
4189 -+ {
4190 -+ { "-", 0, "", 0 },
4191 -+ };
4192 -+
4193 -+ /* This is a CVT hack that makes thick horizontal stems on 2, 5, 7 */
4194 -+ /* similar to Windows XP. */
4195 -+#define TIMES_NEW_ROMAN_HACK_RULES_SIZE 12
4196 -+ SPH_TweakRule TIMES_NEW_ROMAN_HACK_Rules
4197 -+ [TIMES_NEW_ROMAN_HACK_RULES_SIZE] =
4198 -+ {
4199 -+ { "Times New Roman", 16, "Italic", '2' },
4200 -+ { "Times New Roman", 16, "Italic", '5' },
4201 -+ { "Times New Roman", 16, "Italic", '7' },
4202 -+ { "Times New Roman", 16, "Regular", '2' },
4203 -+ { "Times New Roman", 16, "Regular", '5' },
4204 -+ { "Times New Roman", 16, "Regular", '7' },
4205 -+ { "Times New Roman", 17, "Italic", '2' },
4206 -+ { "Times New Roman", 17, "Italic", '5' },
4207 -+ { "Times New Roman", 17, "Italic", '7' },
4208 -+ { "Times New Roman", 17, "Regular", '2' },
4209 -+ { "Times New Roman", 17, "Regular", '5' },
4210 -+ { "Times New Roman", 17, "Regular", '7' },
4211 -+ };
4212 -+
4213 -+
4214 -+ /* This fudges distance on 2 to get rid of the vanishing stem issue. */
4215 -+ /* A real solution to this is certainly welcome. */
4216 -+#define COURIER_NEW_2_HACK_RULES_SIZE 15
4217 -+ SPH_TweakRule COURIER_NEW_2_HACK_Rules
4218 -+ [COURIER_NEW_2_HACK_RULES_SIZE] =
4219 -+ {
4220 -+ { "Courier New", 10, "Regular", '2' },
4221 -+ { "Courier New", 11, "Regular", '2' },
4222 -+ { "Courier New", 12, "Regular", '2' },
4223 -+ { "Courier New", 13, "Regular", '2' },
4224 -+ { "Courier New", 14, "Regular", '2' },
4225 -+ { "Courier New", 15, "Regular", '2' },
4226 -+ { "Courier New", 16, "Regular", '2' },
4227 -+ { "Courier New", 17, "Regular", '2' },
4228 -+ { "Courier New", 18, "Regular", '2' },
4229 -+ { "Courier New", 19, "Regular", '2' },
4230 -+ { "Courier New", 20, "Regular", '2' },
4231 -+ { "Courier New", 21, "Regular", '2' },
4232 -+ { "Courier New", 22, "Regular", '2' },
4233 -+ { "Courier New", 23, "Regular", '2' },
4234 -+ { "Courier New", 24, "Regular", '2' },
4235 -+ };
4236 -+
4237 -+
4238 -+#ifndef FORCE_NATURAL_WIDTHS
4239 -+
4240 -+ /* Use compatible widths with these glyphs. Compatible widths is always */
4241 -+ /* on when doing B/W TrueType instructing, but is used selectively here, */
4242 -+ /* typically on glyphs with 3 or more vertical stems. */
4243 -+#define COMPATIBLE_WIDTHS_RULES_SIZE 36
4244 -+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules
4245 -+ [COMPATIBLE_WIDTHS_RULES_SIZE] =
4246 -+ {
4247 -+ { "Arial Unicode MS", 12, "Regular Class", 'm' },
4248 -+ { "Arial Unicode MS", 14, "Regular Class", 'm' },
4249 -+ { "Arial", 10, "Regular Class", L'ш' },
4250 -+ { "Arial", 11, "Regular Class", 'm' },
4251 -+ { "Arial", 12, "Regular Class", 'm' },
4252 -+ { "Arial", 12, "Regular Class", L'ш' },
4253 -+ { "Arial", 13, "Regular Class", L'ш' },
4254 -+ { "Arial", 14, "Regular Class", 'm' },
4255 -+ { "Arial", 14, "Regular Class", L'ш' },
4256 -+ { "Arial", 15, "Regular Class", L'ш' },
4257 -+ { "Arial", 17, "Regular Class", 'm' },
4258 -+ { "DejaVu Sans", 15, "Regular Class", 0 },
4259 -+ { "Microsoft Sans Serif", 11, "Regular Class", 0 },
4260 -+ { "Microsoft Sans Serif", 12, "Regular Class", 0 },
4261 -+ { "Segoe UI", 11, "Regular Class", 0 },
4262 -+ { "Segoe UI", 12, "Regular Class", 'm' },
4263 -+ { "Segoe UI", 14, "Regular Class", 'm' },
4264 -+ { "Tahoma", 11, "Regular Class", 0 },
4265 -+ { "Times New Roman", 16, "Regular Class", 'c' },
4266 -+ { "Times New Roman", 16, "Regular Class", 'm' },
4267 -+ { "Times New Roman", 16, "Regular Class", 'o' },
4268 -+ { "Times New Roman", 16, "Regular Class", 'w' },
4269 -+ { "Trebuchet MS", 12, "Regular Class", 0 },
4270 -+ { "Trebuchet MS", 14, "Regular Class", 0 },
4271 -+ { "Trebuchet MS", 15, "Regular Class", 0 },
4272 -+ { "Ubuntu", 12, "Regular Class", 'm' },
4273 -+ { "Verdana", 10, "Regular Class", L'ш' },
4274 -+ { "Verdana", 11, "Regular Class", L'ш' },
4275 -+ { "Verdana and Clones", 12, "Regular Class", 'm' },
4276 -+ { "Verdana and Clones", 12, "Regular Class", 'l' },
4277 -+ { "Verdana and Clones", 12, "Regular Class", 'i' },
4278 -+ { "Verdana and Clones", 12, "Regular Class", 'j' },
4279 -+ { "Verdana and Clones", 13, "Regular Class", 'l' },
4280 -+ { "Verdana and Clones", 13, "Regular Class", 'i' },
4281 -+ { "Verdana and Clones", 13, "Regular Class", 'j' },
4282 -+ { "Verdana and Clones", 14, "Regular Class", 'm' },
4283 -+ };
4284 -+
4285 -+
4286 -+ /* Scaling slightly in the x-direction prior to hinting results in */
4287 -+ /* more visually pleasing glyphs in certain cases. */
4288 -+ /* This sometimes needs to be coordinated with compatible width rules. */
4289 -+#define X_SCALING_RULES_SIZE 40
4290 -+ SPH_ScaleRule X_SCALING_Rules
4291 -+ [X_SCALING_RULES_SIZE] =
4292 -+ {
4293 -+ { "DejaVu Sans", 12, "Regular Class", 'm', .95 },
4294 -+ { "Verdana and Clones", 12, "Regular Class", 'a', 1.1 },
4295 -+ { "Arial", 11, "Regular Class", 'm', .975 },
4296 -+ { "Arial", 12, "Regular Class", 'm', 1.05 },
4297 -+ { "Arial", 13, "Regular Class", L'л', .95 },
4298 -+ { "Arial", 14, "Regular Class", 'm', .95 },
4299 -+ { "Arial", 15, "Regular Class", L'л', .925 },
4300 -+ { "Bitstream Vera Sans", 10, "Regular Class", 0, 1.1 },
4301 -+ { "Bitstream Vera Sans", 12, "Regular Class", 0, 1.05},
4302 -+ { "Bitstream Vera Sans", 16, "Regular Class", 0, 1.05 },
4303 -+ { "Bitstream Vera Sans", 9, "Regular Class", 0, 1.05},
4304 -+ { "DejaVu Sans", 12, "Regular Class", 'l', .975 },
4305 -+ { "DejaVu Sans", 12, "Regular Class", 'i', .975 },
4306 -+ { "DejaVu Sans", 12, "Regular Class", 'j', .975 },
4307 -+ { "DejaVu Sans", 13, "Regular Class", 'l', .95 },
4308 -+ { "DejaVu Sans", 13, "Regular Class", 'i', .95 },
4309 -+ { "DejaVu Sans", 13, "Regular Class", 'j', .95 },
4310 -+ { "DejaVu Sans", 10, "Regular Class", 0, 1.1 },
4311 -+ { "DejaVu Sans", 12, "Regular Class", 0, 1.05 },
4312 -+ { "Georgia", 10, "", 0, 1.05 },
4313 -+ { "Georgia", 11, "", 0, 1.1 },
4314 -+ { "Georgia", 12, "", 0, 1.025 },
4315 -+ { "Georgia", 13, "", 0, 1.05 },
4316 -+ { "Georgia", 16, "", 0, 1.05 },
4317 -+ { "Georgia", 17, "", 0, 1.03 },
4318 -+ { "Liberation Sans", 12, "Regular Class", 'm', 1.1 },
4319 -+ { "Lucida Grande", 11, "Regular Class", 'm', 1.1 },
4320 -+ { "Microsoft Sans Serif", 11, "Regular Class", 'm', .95 },
4321 -+ { "Microsoft Sans Serif", 12, "Regular Class", 'm', 1.05 },
4322 -+ { "Segoe UI", 12, "Regular Class", 'H', 1.05 },
4323 -+ { "Segoe UI", 12, "Regular Class", 'm', 1.05 },
4324 -+ { "Segoe UI", 14, "Regular Class", 'm', 1.05 },
4325 -+ { "Tahoma", 11, "Regular Class", 'm', .975 },
4326 -+ { "Verdana", 10, "Regular Class", 0, 1.1 },
4327 -+ { "Verdana", 12, "Regular Class", 'm', .975 },
4328 -+ { "Verdana", 12, "Regular Class", 0, 1.05 },
4329 -+ { "Verdana", 16, "Regular Class", 0, 1.05 },
4330 -+ { "Verdana", 9, "Regular Class", 0, 1.05 },
4331 -+ { "Times New Roman", 16, "Regular Class", 'm', .95 },
4332 -+ { "Trebuchet MS", 12, "Regular Class", 'm', .95 },
4333 -+ };
4334 -+#else
4335 -+#define COMPATIBLE_WIDTHS_RULES_SIZE 1
4336 -+ SPH_TweakRule COMPATIBLE_WIDTHS_Rules
4337 -+ [COMPATIBLE_WIDTHS_RULES_SIZE] =
4338 -+ {
4339 -+ { "-", 0, "", 0 },
4340 -+ };
4341 -+
4342 -+#define X_SCALING_RULES_SIZE 1
4343 -+ SPH_ScaleRule X_SCALING_Rules
4344 -+ [X_SCALING_RULES_SIZE] =
4345 -+ {
4346 -+ { "-", 0, "", 0, 1.0 },
4347 -+ };
4348 -+#endif /* FORCE_NATURAL_WIDTHS */
4349 -+
4350 -+#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4351 -+
4352 -+#endif /* __TTSUBPIX_H__ */
4353 -+
4354 -+/* END */
4355
4356 diff --git a/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch b/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch
4357 deleted file mode 100644
4358 index a9aaea1..0000000
4359 --- a/media-libs/freetype/files/freetype-enable-subpixel-hinting-infinality.patch
4360 +++ /dev/null
4361 @@ -1,21 +0,0 @@
4362 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/include/freetype/config/ftoption.h freetype-subpixel-enabled/include/freetype/config/ftoption.h
4363 ---- freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500
4364 -+++ freetype-subpixel-enabled/include/freetype/config/ftoption.h 2012-06-15 07:32:18.144747500 -0500
4365 -@@ -92,7 +92,7 @@
4366 - /* This is done to allow FreeType clients to run unmodified, forcing */
4367 - /* them to display normal gray-level anti-aliased glyphs. */
4368 - /* */
4369 --/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
4370 -+#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
4371 -
4372 -
4373 - /*************************************************************************/
4374 -@@ -577,7 +577,7 @@
4375 - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */
4376 - /* defined. */
4377 - /* */
4378 --/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */
4379 -+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING
4380 -
4381 -
4382 - /*************************************************************************/
4383
4384 diff --git a/media-libs/freetype/files/freetype-entire-infinality-patchset.patch b/media-libs/freetype/files/freetype-entire-infinality-patchset.patch
4385 deleted file mode 100644
4386 index fcb039e..0000000
4387 --- a/media-libs/freetype/files/freetype-entire-infinality-patchset.patch
4388 +++ /dev/null
4389 @@ -1,4630 +0,0 @@
4390 -freetype-entire-infinality-patchset-20120615-01.patch
4391 --------------------------------------------------------------------
4392 -(excludes the TT subpixel patches, which are required )
4393 -
4394 -This should patch to a subpixel-patched Freetype 2.4.10. Additional
4395 -required files are also contained in the zipfile here:
4396 -
4397 -http://www.infinality.net/blog/infinality-freetype-patches/
4398 -
4399 -You will need to include this file in your profile with something like:
4400 - /etd/profile.d/infinality-settings.sh
4401 -
4402 -You'll need a file named (for 64 bit)
4403 -/etc/ld.so.conf.d/freetype-infinality-x86_64.conf that contains:
4404 -/usr/lib64/freetype-infinality
4405 -
4406 -Or a file named (for 32 bit)
4407 -/etc/ld.so.conf.d/freetype-infinality-i386.conf that contains:
4408 -/usr/lib/freetype-infinality
4409 -
4410 -Please see each file for more detailed information.
4411 -
4412 -If you are using this patch, you should also use the fontconfig configuration
4413 -also found at the above link.
4414 -
4415 -The fedora packages I provide take care of all this for you.
4416 -
4417 -
4418 -
4419 -DISCLAIMERS:
4420 -
4421 -This patch will almost certainly result in a performance hit when
4422 -freetype is rendering the glyphs. The good news is that fontconfig
4423 -caches the glyphs so it's only the first time they are displayed that there
4424 -could be a performance issue.
4425 -
4426 -I expect that if you compile freetype with this patch along with my
4427 -TT subpixel hinting patch, you will have a complete build that works the
4428 -way I expect it to. However, I have not tested all compile configurations
4429 -for errors. I intend to at some point. This patch may make your system crash,
4430 -have memory leaks, not compile, or render fonts in a way that you don't like.
4431 -Either way, when you use this patch, you should recognize that it
4432 -is ALPHA / BETA quality. That said, I intend to run these patches on my
4433 -personal system, so they had better be pretty stable!
4434 -
4435 -
4436 -
4437 -Changes for 2012-06-15:
4438 -
4439 -Infinality autohint patches:
4440 - * Fix the forced slight hinting logic
4441 - * Enhance artificial emboldening at larger ppems
4442 -
4443 -Infinality subpixel patches:
4444 - * Substantial simplification of the TT rules, which helps with all the rest of the following improvements.
4445 - * Preparation for submission into Freetype tree.
4446 - * Update to Freetype 2.4.10
4447 - * Fix Ubuntu S M N
4448 - * Courier fixes
4449 - * Make all fonts use standard (non-subpixel) TT hinting for characters '>' and '<'.
4450 - * Marked improvement on many non-Latin fonts, including Meiryo.
4451 - * Fix Oxygen rendering if usint TT hinting, and other ttfautohinted fonts
4452 - * Code cleanup
4453 -
4454 -Infinality Fontconfig Package:
4455 - * Add more fonts to the TT hinted list
4456 - * Fixes for font alias (thanks Yegorius)
4457 -
4458 -
4459 -Changes for 2012-04-03:
4460 -
4461 -Fixes:
4462 -
4463 - * Get rid of TT_CONFIG_OPTION_SUBPIXEL_HINTING_ADDITIONAL_TWEAKS
4464 - and do this by default if TT_CONFIG_OPTION_SUBPIXEL_HINTING is enabled.
4465 - * Update to Freetype 2.4.9
4466 - * Fix sdl_ttf rendering
4467 - * Code cleanup
4468 - * Prevent crashes in OSX mode (thanks Markser)
4469 -
4470 -
4471 -Changes for 2011-12-23:
4472 -
4473 -Fixes / Tweaks:
4474 - * Courier New Hack for '2'.
4475 - * Tweak Arial 16px a bit.
4476 - * Various tweaks on Courier New, Times NR, Arial, Verdana and others that
4477 - create a general improvement in appearance at certain ppems.
4478 - * Fixes on some Cyrillic glyphs.
4479 - * Pragmata Pro and Pragmata added to patches.
4480 - * Be a little more conservative in the way "known settings" of fonts are done.
4481 - * Many small improvements to the subpixel hinting patch.
4482 - * Fix a crasher in the Windows sharpening algorithm.
4483 - * Noticible improvement on spacing in Tahoma 11px, Arial 11px, and other Arial
4484 - clones. Me likey.
4485 - * Code fixes to prevent some warnings and possible crashes. (Thanks banta)
4486 - * Fix Opera and Firefox crashes. slot->face->style_name and
4487 - slot->face->family_name need to be checked for not NULL before using.
4488 -
4489 -
4490 -Changes for 2011-11-17:
4491 -
4492 -Features:
4493 - * Added a post-render, pre-lcd-filter filter that attempts to duplicate windows
4494 - sharpness / graininess. Controlled by
4495 - INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH.
4496 - * Added a fringe filter, intended mostly for autohint (but still effective
4497 - for certain cases of TT hinting). This attempts to remove gray fringes that
4498 - sometimes occur on horizontal stems and angled serifs and doodads
4499 - (Times, Segoe '1', etc.)
4500 - * Added a grayscale filter.
4501 - * Added brightness/contrast filter.
4502 - * Substantial improvements in the stem alignment algorithm! Wow!
4503 - * Stem alignment now also happens on grayscale antialiased fonts (rgba=none).
4504 -
4505 -Fixes / Tweaks:
4506 - * Changes inside of local.conf, which are documented there.
4507 - * Removed an artificial shift of 1/8 pixel to the right on stem aligned glyphs
4508 - which should result in sharper looking alignment.
4509 - * Added XFT_SETTINGS into infinality-settings.sh. This means it will require
4510 - less configuration on the end-user side.
4511 - * Fixed code to not touch bold, thin, narrow or italic faces for scale or
4512 - alignment (until they can be properly accounted for).
4513 - * Added -lm dependency to the code again. (It seems to sneak off now and then)
4514 - * Changed autohinter horizontal stem stem snapping from on/off to use a value
4515 - between 0 and 100.
4516 - * Functions getenv() and system() were crashing evince in _lcd_stem_align()
4517 - at odd times. A workaround has been put in place.
4518 - * Moved _lcd_stem_align and all other filters into ftsmooth.c, which is a better place.
4519 - * Use malloc() in _lcd_stem_align for allocating structs and arrays of structs
4520 - instead of what I learned in C++ class 10+ years ago. Should prevent abiword
4521 - from crashing with large pt sizes like 3000. (A workaround has been put
4522 - in place to automatically skip alignment on any ppem > 100. This will
4523 - prevent the crashes until the real solution can be figured out.)
4524 - * Fix some compiler warnings. Some are still present.
4525 - * Added "m" control to alignment algorithm. This will cause all stems to m
4526 - (or other 3-pronged glyphs) to get aligned to pixels. It still needs a bit
4527 - of work, as it makes the best looking glyph size change. This is because
4528 - the glyph now needs to snap stems to only even or odd pixels, not single ones.
4529 - * Added rules to allow "compatible widths" (i.e. widths if the font were being
4530 - bitmap TT hinted) on a glyph by glyph basis and tweaked certain fonts like
4531 - arial, verdana, times new roman, segoe ui, and trebuchet to use them.
4532 - * Don't stem align anything below 9 ppem because it is not consistently good.
4533 - * When doing stem alignment, automatically align stems to center of pixel or
4534 - start of pixel when necessary. When horizontal stems start snapping to 2 px,
4535 - so should the vertical ones in order for it to look nice.
4536 - * A Verdana 12 hack to make it render more like Windows. This notoriously
4537 - poor looking ppem now looks as good as Verdana 13 without needing fontconfig
4538 - replacement.
4539 - * Courier New now looks good, and possibly better than Windows rendering, with
4540 - TT or autohint rendering. By the way, the hinters of Courier New should
4541 - either be commended or executed.
4542 - * Improvements in overshoot artifact and fringe correction- Freesans at large
4543 - ppem looks nice now. Overshoots on letters like 6, g, s, 3, etc. will
4544 - now be rounded to integer pixels.
4545 - * Wrap all infinality code within a macro that is set in ftoption.h:
4546 - #ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET. Makes it easier to identify
4547 - in the code and allows for easy compliation with or without the patches set.
4548 - * Variable renaming for more clarity, in code and in environment variables.
4549 - * Move stretching code into Freetype instead of relying on programs to handle
4550 - fontconfig matrix (they SUCK at it... *cough* Chrome *cough*).
4551 - * Additional modifications to the TT subpixel rendering rules for corrections
4552 - to Georgia, DejaVu Sans, Times New Roman, Courier New and a couple others.
4553 - * A general improvement in the way autohinted fonts render, particularly on
4554 - ones that normally look fragile or thin. Examples include Optima, Freemono,
4555 - Freeserif, Raleway, MgOpen, etc. I'm doing what Windows does, which is
4556 - brightness/contrast adjustment, except you don't see rainbows.
4557 -
4558 -
4559 -Changes for 2011-06-04:
4560 - MISSING
4561 -
4562 - ====================================================================
4563 - ============= ANYTHING BELOW HERE MAY BE INACCURATE NOW ============
4564 - ====================================================================
4565 -
4566 -Changes for 2010-11-14:
4567 - * Rule tweaks on various fonts. Fixed the Cyrillic y issue and e issue
4568 - with Trebuchet, and the ^ issue with Arial. Other issues
4569 - (firefox and @font-face) are still present to a degree.
4570 -
4571 - * A couple new rules to deal with various issues. (work in progress)
4572 -
4573 - * Additional commenting.
4574 -
4575 - * Some cleanup of obsolete code.
4576 -
4577 - * Added some debugging code for potential future enhancements. Please
4578 - ignore the mess.
4579 -
4580 -
4581 -Changes for 2010-10-22:
4582 - * I'm refocusing on just getting the subpixel looking nice, so I've stripped
4583 - back the rendering modes to just 2. The standard SUBPIXEL_HINTING and
4584 - the ADDITIONAL_TWEAKS. The rules structure is still in place. I recommend
4585 - using ADDITIONAL_TWEAKS mode.
4586 -
4587 - * Fixed an issue with monochrome rendering that made fonts look really bad.
4588 - There is still an issue with them, but they are at least tolerable to
4589 - look at now.
4590 -
4591 - * Added some testing code for detecting inline delta functions. Not sure
4592 - if this is useful yet.
4593 -
4594 - * Added more rules to deal with certain artifacts on various fonts, like the
4595 - issue with < > and ^. Created some "exception" rules for certain rules.
4596 -
4597 - * Reverted back to older rounding functions. The new experimental ones I
4598 - was trying were causing artifacts on some fonts.
4599 -
4600 - * Some code cleanup.
4601 -
4602 -
4603 -Changes for 2010-10-08:
4604 - * Fix PDF crashes.
4605 -
4606 -Changes for 2010-10-04:
4607 - * Update to freetype-2.4.3
4608 -
4609 -
4610 -Changes for 2010-10-03:
4611 - * There are lots of changes for this one, some big, some small, and some
4612 - that still are not implemented. Not sure if I can remember them all
4613 - but I will try! THIS IS A POINT RELEASE THAT IS NOT
4614 - INTENDED TO WORK 100%. Some fonts and compile options may be broken
4615 - and the code may be inefficient and/or not syntactiacally correct.
4616 - That said, I do plan on using this on my system right away.
4617 -
4618 - * There are now "rendering modes" for the subpixel hinting, with the idea
4619 - that this will enventually be able to be controlled by fontconfig. The 4
4620 - modes of enhanced hinting defined so far are:
4621 - 1) NATIVE HINTING - this is what freetype TT interpreter does by default.
4622 - 2) FIXED NATIVE HINTING - A slighly tweaked version of the above that
4623 - does "better" native rendering when displaying on LCD, for those
4624 - that still seem to like incorrect, thin fonts, which were only ever
4625 - there due to technical limitations.
4626 - 3) SUBPIXEL OPTIMIZED HINTING - this is straight up subpixel hinting with
4627 - very few tweaks. Just enough to get it working.
4628 - 4) COMPATIBILITY MODE HINTING - this is the sweet spot I'm working on
4629 - that will hopefully supplant #3 because it will work so well with all
4630 - fonts. The idea here is to tweak all available fonts so that each
4631 - renders well.
4632 - All of these modes either turn on or off switches in the interpreter
4633 - to make the fonts render properly for each mode. Right now these are only
4634 - compile-time options.
4635 -
4636 - * Subpixel-related code has been broken out into its own files, so as to not
4637 - clutter up the existing code.
4638 -
4639 - * The rasterizer now pays attention to the additional bits of MS rasterizer
4640 - v. 37, meaning that it can now indicate to fonts that it can handle
4641 - subpixel rendering.
4642 -
4643 - * The rounding functions have been adapted to accept a grid resolution
4644 - variable, which lets them work on pixel and subpixel boundaries
4645 - automatically. Y still needs to be implemented.
4646 -
4647 - * Additional conditions have been added to the switches, to further refine
4648 - how they are applied to different fonts.
4649 -
4650 - * What all this means qualitatively is that legacy fonts now render much
4651 - better. There are still some that need a bit of love, like Courier New.
4652 -
4653 - - Courier New has some fixes, and some breakage (Ghost pixels above bold
4654 - fonts, too thin on regular font)
4655 - - Times New Roman has some fixes and breakage (serifs, particularly)
4656 - - Tahoma and Trebuchet MS have been cleaned up
4657 - - Arial now snaps to grid better, but that causes breakage on a few glyphs
4658 - - Verdana 13 is now set to grid fit, but some glyhs are broken (mwxyz)
4659 - - Geneva and Geneva CY no longer look like turds
4660 - - Lucida Sans Unicode now looks arguably better than Lucida Grande
4661 -
4662 -
4663 -
4664 -Changes for 2010-09-16:
4665 -
4666 - * The changes from 2010-09-14 regarding subpixel when LIGHT hinting enabled
4667 - have been reverted due to problems. The old behavior is back.
4668 -
4669 - * Disable grayscale when subpixel is enabled. This results in better
4670 - behavior of some TT instructions within some fonts, like Times New Roman.
4671 -
4672 - * Some modification of the tweaks, in light of above.
4673 -
4674 -
4675 -Changes for 2010-09-14:
4676 -
4677 - /************************** NO LONGER IN PLACE *****************************/
4678 - * Subpixel hinting is now used when the LIGHT hinting method and the TT
4679 - hinting is called. If FULL hinting is requested it will do the usual
4680 - behavior of the TT hinter.
4681 -
4682 - This allows for all previously existing behavior, plus the new subpixel
4683 - hinting behavior, all in the same compile, and it makes sense in that
4684 - the slight hinting of the autohinter is essentially doing the same thing
4685 - as this, which is not forcing X-direction hints.
4686 -
4687 - Previously, even if TT was selected, but LIGHT hinting was used, the
4688 - autohinter would still be forced. Other than this, autohint is not affected.
4689 - /***************************************************************************/
4690 -
4691 - * Added a couple more conditionals around things to test whether subpixel
4692 - hinting is enabled. There were a few missing that ended up causing some
4693 - goofy hinting if subpixel was not enabled, but compiled in.
4694 -
4695 -
4696 -
4697 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/configure freetype-work/configure
4698 ---- freetype-subpixel/configure 2011-12-02 13:21:55.000000000 -0600
4699 -+++ freetype-work/configure 2012-06-15 07:42:34.983820793 -0500
4700 -@@ -13,6 +13,8 @@
4701 - # Call the `configure' script located in `builds/unix'.
4702 - #
4703 -
4704 -+export LDFLAGS="$LDFLAGS -lm"
4705 -+
4706 - rm -f config.mk builds/unix/unix-def.mk builds/unix/unix-cc.mk
4707 -
4708 - if test "x$GNUMAKE" = x; then
4709 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/devel/ftoption.h freetype-work/devel/ftoption.h
4710 ---- freetype-subpixel/devel/ftoption.h 2012-06-15 07:31:12.119986648 -0500
4711 -+++ freetype-work/devel/ftoption.h 2012-06-15 17:21:09.266008295 -0500
4712 -@@ -577,6 +577,17 @@
4713 -
4714 - /*************************************************************************/
4715 - /* */
4716 -+ /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */
4717 -+ /* all additional infinality patches, which are configured via env */
4718 -+ /* variables. */
4719 -+ /* */
4720 -+ /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */
4721 -+ /* defined. */
4722 -+ /* */
4723 -+#define FT_CONFIG_OPTION_INFINALITY_PATCHSET
4724 -+
4725 -+ /*************************************************************************/
4726 -+ /* */
4727 - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
4728 - /* of the TrueType bytecode interpreter is used that doesn't implement */
4729 - /* any of the patented opcodes and algorithms. The patents related to */
4730 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/include/freetype/config/ftoption.h freetype-work/include/freetype/config/ftoption.h
4731 ---- freetype-subpixel/include/freetype/config/ftoption.h 2012-06-15 07:31:12.146985731 -0500
4732 -+++ freetype-work/include/freetype/config/ftoption.h 2012-06-15 17:21:08.490034299 -0500
4733 -@@ -577,6 +577,17 @@
4734 -
4735 - /*************************************************************************/
4736 - /* */
4737 -+ /* Define FT_CONFIG_OPTION_INFINALITY_PATCHSET if you want to enable */
4738 -+ /* all additional infinality patches, which are configured via env */
4739 -+ /* variables. */
4740 -+ /* */
4741 -+ /* This option requires TT_CONFIG_OPTION_SUBPIXEL_HINTING to */
4742 -+ /* defined. */
4743 -+ /* */
4744 -+#define FT_CONFIG_OPTION_INFINALITY_PATCHSET
4745 -+
4746 -+ /*************************************************************************/
4747 -+ /* */
4748 - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */
4749 - /* of the TrueType bytecode interpreter is used that doesn't implement */
4750 - /* any of the patented opcodes and algorithms. The patents related to */
4751 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/autofit/aflatin.c freetype-work/src/autofit/aflatin.c
4752 ---- freetype-subpixel/src/autofit/aflatin.c 2012-06-14 00:35:58.000000000 -0500
4753 -+++ freetype-work/src/autofit/aflatin.c 2012-06-15 07:42:35.021819509 -0500
4754 -@@ -22,6 +22,7 @@
4755 -
4756 - #include "aflatin.h"
4757 - #include "aferrors.h"
4758 -+#include "strings.h"
4759 -
4760 -
4761 - #ifdef AF_CONFIG_OPTION_USE_WARPER
4762 -@@ -528,7 +529,30 @@
4763 - FT_Pos delta;
4764 - AF_LatinAxis axis;
4765 - FT_UInt nn;
4766 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4767 -+ int checked_adjust_heights_env = 0;
4768 -+ FT_Bool adjust_heights = FALSE;
4769 -
4770 -+ if ( checked_adjust_heights_env == 0 )
4771 -+ {
4772 -+ char *adjust_heights_env = getenv( "INFINALITY_FT_AUTOHINT_INCREASE_GLYPH_HEIGHTS" );
4773 -+ if ( adjust_heights_env != NULL )
4774 -+ {
4775 -+ if ( strcasecmp(adjust_heights_env, "default" ) != 0 )
4776 -+ {
4777 -+ if ( strcasecmp(adjust_heights_env, "true") == 0)
4778 -+ adjust_heights = TRUE;
4779 -+ else if ( strcasecmp(adjust_heights_env, "1") == 0)
4780 -+ adjust_heights = TRUE;
4781 -+ else if ( strcasecmp(adjust_heights_env, "on") == 0)
4782 -+ adjust_heights = TRUE;
4783 -+ else if ( strcasecmp(adjust_heights_env, "yes") == 0)
4784 -+ adjust_heights = TRUE;
4785 -+ }
4786 -+ }
4787 -+ checked_adjust_heights_env = 1;
4788 -+ }
4789 -+#endif
4790 -
4791 - if ( dim == AF_DIMENSION_HORZ )
4792 - {
4793 -@@ -556,7 +580,7 @@
4794 - {
4795 - AF_LatinAxis Axis = &metrics->axis[AF_DIMENSION_VERT];
4796 - AF_LatinBlue blue = NULL;
4797 --
4798 -+ int threshold = 40;
4799 -
4800 - for ( nn = 0; nn < Axis->blue_count; nn++ )
4801 - {
4802 -@@ -566,12 +590,16 @@
4803 - break;
4804 - }
4805 - }
4806 --
4807 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4808 -+ if ( adjust_heights
4809 -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15
4810 -+ && metrics->root.scaler.face->size->metrics.x_ppem > 5 )
4811 -+ threshold = 52;
4812 -+#endif
4813 - if ( blue )
4814 - {
4815 - FT_Pos scaled = FT_MulFix( blue->shoot.org, scaler->y_scale );
4816 -- FT_Pos fitted = ( scaled + 40 ) & ~63;
4817 --
4818 -+ FT_Pos fitted = ( scaled + threshold ) & ~63;
4819 -
4820 - if ( scaled != fitted )
4821 - {
4822 -@@ -626,7 +654,6 @@
4823 - AF_LatinBlue blue = &axis->blues[nn];
4824 - FT_Pos dist;
4825 -
4826 --
4827 - blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta;
4828 - blue->ref.fit = blue->ref.cur;
4829 - blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta;
4830 -@@ -635,7 +662,12 @@
4831 -
4832 - /* a blue zone is only active if it is less than 3/4 pixels tall */
4833 - dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale );
4834 -+
4835 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4836 -+ /* Do always, in order to prevent fringes */
4837 -+#else
4838 - if ( dist <= 48 && dist >= -48 )
4839 -+#endif
4840 - {
4841 - #if 0
4842 - FT_Pos delta1;
4843 -@@ -686,7 +718,12 @@
4844 - delta2 = -delta2;
4845 -
4846 - blue->ref.fit = FT_PIX_ROUND( blue->ref.cur );
4847 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4848 -+ /* Round to prevent fringes */
4849 -+ blue->shoot.fit = FT_PIX_ROUND( blue->ref.fit - delta2 );
4850 -+#else
4851 - blue->shoot.fit = blue->ref.fit - delta2;
4852 -+#endif
4853 -
4854 - #endif
4855 -
4856 -@@ -1433,6 +1470,8 @@
4857 - if ( dist < 0 )
4858 - dist = -dist;
4859 -
4860 -+ /* round down to pixels */
4861 -+ /*dist = FT_MulFix( dist, scale ) & ~63;*/
4862 - dist = FT_MulFix( dist, scale );
4863 - if ( dist < best_dist )
4864 - {
4865 -@@ -1595,20 +1634,95 @@
4866 - FT_Pos dist = width;
4867 - FT_Int sign = 0;
4868 - FT_Int vertical = ( dim == AF_DIMENSION_VERT );
4869 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4870 -+ FT_Int infinality_dist = 0;
4871 -
4872 -
4873 -- if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
4874 -- axis->extra_light )
4875 -- return width;
4876 -+
4877 -+ FT_UInt autohint_snap_stem_height = 0;
4878 -+ FT_UInt checked_autohint_snap_stem_height = 0;
4879 -+
4880 -+ if ( checked_autohint_snap_stem_height == 0)
4881 -+ {
4882 -+ char *autohint_snap_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_SNAP_STEM_HEIGHT" );
4883 -+ if ( autohint_snap_stem_height_env != NULL )
4884 -+ {
4885 -+ sscanf ( autohint_snap_stem_height_env, "%u", &autohint_snap_stem_height );
4886 -+ if (autohint_snap_stem_height > 100 ) autohint_snap_stem_height = 100;
4887 -+ else if (autohint_snap_stem_height < 0 ) autohint_snap_stem_height = 0;
4888 -+ }
4889 -+ checked_autohint_snap_stem_height = 1;
4890 -+ }
4891 -+
4892 -+ if ( autohint_snap_stem_height == 0 )
4893 -+#endif
4894 -+ if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ||
4895 -+ axis->extra_light )
4896 -+ return width;
4897 -
4898 - if ( dist < 0 )
4899 - {
4900 - dist = -width;
4901 - sign = 1;
4902 - }
4903 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4904 -+ /* Calculate snap value differently than standard freetype */
4905 -+ if ( /* stem_snap_light*/ autohint_snap_stem_height > 0
4906 -+ && (
4907 -+ ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) )
4908 -+ || ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) )
4909 -+ {
4910 -+ infinality_dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
4911 -+
4912 -+ if ( metrics->root.scaler.face->size->metrics.x_ppem > 9
4913 -+ && axis->width_count > 0
4914 -+ && abs ( axis->widths[0].cur - infinality_dist ) < 32
4915 -+ && axis->widths[0].cur > 52 )
4916 -+ {
4917 -+ if ( strstr(metrics->root.scaler.face->style_name, "Regular")
4918 -+ || strstr(metrics->root.scaler.face->style_name, "Book")
4919 -+ || strstr(metrics->root.scaler.face->style_name, "Medium")
4920 -+ || strcmp(metrics->root.scaler.face->style_name, "Italic") == 0
4921 -+ || strcmp(metrics->root.scaler.face->style_name, "Oblique") == 0 )
4922 -+ {
4923 -+ /* regular weight */
4924 -+ if ( axis->widths[0].cur < 64 ) infinality_dist = 64 ;
4925 -+ else if (axis->widths[0].cur < 88) infinality_dist = 64;
4926 -+ else if (axis->widths[0].cur < 160) infinality_dist = 128;
4927 -+ else if (axis->widths[0].cur < 240) infinality_dist = 190;
4928 -+ else infinality_dist = ( infinality_dist ) & ~63;
4929 -+ }
4930 -+ else
4931 -+ {
4932 -+ /* bold gets a different threshold */
4933 -+ if ( axis->widths[0].cur < 64 ) infinality_dist = 64 ;
4934 -+ else if (axis->widths[0].cur < 108) infinality_dist = 64;
4935 -+ else if (axis->widths[0].cur < 160) infinality_dist = 128;
4936 -+ else if (axis->widths[0].cur < 222) infinality_dist = 190;
4937 -+ else if (axis->widths[0].cur < 288) infinality_dist = 254;
4938 -+ else infinality_dist = ( infinality_dist + 16 ) & ~63;
4939 -+ }
4940 -+
4941 -+ }
4942 -+ if (infinality_dist < 52)
4943 -+ {
4944 -+ if (metrics->root.scaler.face->size->metrics.x_ppem < 9 )
4945 -+ {
4946 -+
4947 -+ if (infinality_dist < 32) infinality_dist = 32;
4948 -+ }
4949 -+ else
4950 -+ infinality_dist = 64;
4951 -+ }
4952 -+ }
4953 -+ else if ( autohint_snap_stem_height < 100
4954 -+ && (( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
4955 -+ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) )
4956 -+#else
4957 -
4958 -- if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
4959 -- ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
4960 -+ if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||
4961 -+ ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )
4962 -+#endif
4963 - {
4964 - /* smooth hinting process: very lightly quantize the stem width */
4965 -
4966 -@@ -1667,7 +1781,10 @@
4967 - dist = ( dist + 32 ) & ~63;
4968 - }
4969 - }
4970 -- else
4971 -+ else
4972 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4973 -+ if ( autohint_snap_stem_height < 100 )
4974 -+#endif
4975 - {
4976 - /* strong hinting process: snap the stem width to integer pixels */
4977 -
4978 -@@ -1675,7 +1792,9 @@
4979 -
4980 -
4981 - dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
4982 --
4983 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4984 -+ if ( autohint_snap_stem_height > 0 ) goto Done_Width;
4985 -+#endif
4986 - if ( vertical )
4987 - {
4988 - /* in the case of vertical hinting, always round */
4989 -@@ -1738,6 +1857,23 @@
4990 - }
4991 -
4992 - Done_Width:
4993 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
4994 -+ if (axis->widths[0].cur > 42 )
4995 -+ /* weighted average */
4996 -+ dist = (dist * (100 - autohint_snap_stem_height) + infinality_dist * autohint_snap_stem_height ) / 100;
4997 -+
4998 -+ {
4999 -+ int factor = 100;
5000 -+ if (axis->standard_width < 100)
5001 -+ factor = axis->standard_width;
5002 -+
5003 -+ if (metrics->root.scaler.face->size->metrics.x_ppem >=9 && dist < 52 ) dist += ((52 - dist) * factor) / 100;
5004 -+ if (metrics->root.scaler.face->size->metrics.x_ppem <9 && dist < 32 ) dist += ((32 - dist) * factor) / 100;
5005 -+
5006 -+ if (axis->standard_width > 100 && metrics->root.scaler.face->size->metrics.x_ppem >=11 && dist < 64 ) dist = 64;
5007 -+ if (axis->standard_width > 100 && metrics->root.scaler.face->size->metrics.x_ppem >=9 && dist < 52 ) dist = 52;
5008 -+ }
5009 -+#endif
5010 - if ( sign )
5011 - dist = -dist;
5012 -
5013 -@@ -1760,6 +1896,8 @@
5014 - (AF_Edge_Flags)base_edge->flags,
5015 - (AF_Edge_Flags)stem_edge->flags );
5016 -
5017 -+/* if fitted_width causes stem_edge->pos to land basically on top of an existing
5018 -+ * stem_edge->pos, then add or remove 64. Need to figure out a way to do this */
5019 -
5020 - stem_edge->pos = base_edge->pos + fitted_width;
5021 -
5022 -@@ -2234,8 +2372,32 @@
5023 - {
5024 - FT_Error error;
5025 - int dim;
5026 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5027 -+ int emboldening_strength = 0;
5028 -
5029 -+ int checked_use_various_tweaks_env = 0;
5030 -+ FT_Bool use_various_tweaks = FALSE;
5031 -
5032 -+ if ( checked_use_various_tweaks_env == 0 )
5033 -+ {
5034 -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
5035 -+ if ( use_various_tweaks_env != NULL )
5036 -+ {
5037 -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 )
5038 -+ {
5039 -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0)
5040 -+ use_various_tweaks = TRUE;
5041 -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0)
5042 -+ use_various_tweaks = TRUE;
5043 -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0)
5044 -+ use_various_tweaks = TRUE;
5045 -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0)
5046 -+ use_various_tweaks = TRUE;
5047 -+ }
5048 -+ }
5049 -+ checked_use_various_tweaks_env = 1;
5050 -+ }
5051 -+#endif
5052 - error = af_glyph_hints_reload( hints, outline );
5053 - if ( error )
5054 - goto Exit;
5055 -@@ -2292,7 +2454,54 @@
5056 - }
5057 - }
5058 - af_glyph_hints_save( hints, outline );
5059 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5060 -+#if 0
5061 -+ if( metrics->root.scaler.face->style_name )
5062 -+ {
5063 -+ if ( strcasestr(metrics->root.scaler.face->style_name, "Bold")
5064 -+ || strcasestr(metrics->root.scaler.face->style_name, "Black")
5065 -+ || strcasestr(metrics->root.scaler.face->style_name, "Narrow")
5066 -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15
5067 -+ || strcasestr(metrics->root.scaler.face->style_name, "Condensed")
5068 -+ && metrics->root.scaler.face->size->metrics.x_ppem < 20 )
5069 -+ goto Exit;
5070 -+ }
5071 -+ if( metrics->root.scaler.face->family_name )
5072 -+ {
5073 -+ if ( strcasestr(metrics->root.scaler.face->family_name, "Bold")
5074 -+ || strcasestr(metrics->root.scaler.face->family_name, "Black")
5075 -+ || strcasestr(metrics->root.scaler.face->family_name, "Narrow")
5076 -+ && metrics->root.scaler.face->size->metrics.x_ppem < 15
5077 -+ || strcasestr(metrics->root.scaler.face->family_name, "Condensed")
5078 -+ && metrics->root.scaler.face->size->metrics.x_ppem < 20 )
5079 -+ goto Exit;
5080 -+ }
5081 -
5082 -+ /* if the font is particularly thin, embolden it, up to 1 px */
5083 -+ if ( use_various_tweaks
5084 -+ && metrics->axis->widths[0].cur <= FT_MulDiv ( autohint_minimum_stem_width, 64, 100)
5085 -+ && !( dim == AF_DIMENSION_VERT )
5086 -+ && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) )
5087 -+ {
5088 -+ if ( metrics->axis->widths[0].cur
5089 -+ / metrics->root.scaler.face->size->metrics.x_ppem < 5 )
5090 -+ {
5091 -+ emboldening_strength = FT_MulDiv ( autohint_minimum_stem_width, 64, 100) - metrics->axis->widths[0].cur;
5092 -+ if ( metrics->root.scaler.face->size->metrics.x_ppem < 9 )
5093 -+ emboldening_strength -= 10;
5094 -+ if ( metrics->root.scaler.face->size->metrics.x_ppem < 7 )
5095 -+ emboldening_strength -= 10;
5096 -+ }
5097 -+ if ( emboldening_strength < 0 ) emboldening_strength = 0;
5098 -+ FT_Outline_Embolden(outline,emboldening_strength);
5099 -+ }
5100 -+#endif
5101 -+ /* Save this width for use in ftsmooth.c. This is a shameful hack */
5102 -+ const char* c1 = "CUR_WIDTH";
5103 -+ char c2[8];
5104 -+ snprintf(c2,8,"%ld",metrics->axis->widths[0].cur);
5105 -+ setenv(c1, c2, 1);
5106 -+#endif
5107 - Exit:
5108 - return error;
5109 - }
5110 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftlcdfil.c freetype-work/src/base/ftlcdfil.c
5111 ---- freetype-subpixel/src/base/ftlcdfil.c 2010-04-01 03:18:57.000000000 -0500
5112 -+++ freetype-work/src/base/ftlcdfil.c 2012-06-15 07:42:35.022819476 -0500
5113 -@@ -21,6 +21,9 @@
5114 - #include FT_IMAGE_H
5115 - #include FT_INTERNAL_OBJECTS_H
5116 -
5117 -+#include <math.h>
5118 -+#include <string.h>
5119 -+#include <strings.h>
5120 -
5121 - #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
5122 -
5123 -@@ -287,10 +290,51 @@
5124 - { 0x00, 0x55, 0x56, 0x55, 0x00 };
5125 - /* the values here sum up to a value larger than 256, */
5126 - /* providing a cheap gamma correction */
5127 -- static const FT_Byte default_filter[5] =
5128 -+ static FT_Byte default_filter[5] =
5129 - { 0x10, 0x40, 0x70, 0x40, 0x10 };
5130 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5131 -+ int checked_filter_params_env = 0;
5132 -
5133 -+ if ( checked_filter_params_env == 0 )
5134 -+ {
5135 -+ char *filter_params = getenv( "INFINALITY_FT_FILTER_PARAMS" );
5136 -+ if ( filter_params != NULL && strcmp(filter_params, "") != 0 )
5137 -+ {
5138 -+ float f1, f2, f3, f4, f5;
5139 -+
5140 -+ if ( strcasecmp(filter_params, "default" ) != 0)
5141 -+ {
5142 -+ int args_assigned = 0;
5143 -+ args_assigned = sscanf ( filter_params, "%f %f %f %f %f", &f1, &f2, &f3, &f4, &f5 );
5144 -
5145 -+ if ( args_assigned == 5 )
5146 -+ {
5147 -+ if ( f1 + f2 + f3 + f4 + f5 > 5 )
5148 -+ {
5149 -+ /* Assume we were given integers instead of floats */
5150 -+ /* 0 to 100 */
5151 -+ default_filter[0] = (FT_Byte) (f1 * 2.55f + 0.5f);
5152 -+ default_filter[1] = (FT_Byte) (f2 * 2.55f + 0.5f);
5153 -+ default_filter[2] = (FT_Byte) (f3 * 2.55f + 0.5f);
5154 -+ default_filter[3] = (FT_Byte) (f4 * 2.55f + 0.5f);
5155 -+ default_filter[4] = (FT_Byte) (f5 * 2.55f + 0.5f);
5156 -+ }
5157 -+ else
5158 -+ {
5159 -+ /* Assume we were given floating point values */
5160 -+ /* 0 to 1.0 */
5161 -+ default_filter[0] = (FT_Byte) (f1 * 255.0f + 0.5f);
5162 -+ default_filter[1] = (FT_Byte) (f2 * 255.0f + 0.5f);
5163 -+ default_filter[2] = (FT_Byte) (f3 * 255.0f + 0.5f);
5164 -+ default_filter[3] = (FT_Byte) (f4 * 255.0f + 0.5f);
5165 -+ default_filter[4] = (FT_Byte) (f5 * 255.0f + 0.5f);
5166 -+ }
5167 -+ }
5168 -+ }
5169 -+ }
5170 -+ checked_filter_params_env = 1;
5171 -+ }
5172 -+#endif
5173 - if ( !library )
5174 - return FT_Err_Invalid_Argument;
5175 -
5176 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftobjs.c freetype-work/src/base/ftobjs.c
5177 ---- freetype-subpixel/src/base/ftobjs.c 2012-06-14 00:35:58.000000000 -0500
5178 -+++ freetype-work/src/base/ftobjs.c 2012-06-15 07:42:35.025819374 -0500
5179 -@@ -513,6 +513,22 @@
5180 - ft_lookup_glyph_renderer( FT_GlyphSlot slot );
5181 -
5182 -
5183 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5184 -+ static void
5185 -+ ft_glyphslot_enlarge_metrics( FT_GlyphSlot slot,
5186 -+ FT_Render_Mode mode )
5187 -+ {
5188 -+ FT_Glyph_Metrics* metrics = &slot->metrics;
5189 -+ FT_Pos enlarge_cbox = 0;
5190 -+ /* enlarge for grayscale rendering */
5191 -+ if ( mode == FT_RENDER_MODE_NORMAL ) enlarge_cbox = 64;
5192 -+
5193 -+ metrics->horiBearingX -= enlarge_cbox;
5194 -+ metrics->width += 2*enlarge_cbox;
5195 -+ }
5196 -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
5197 -+
5198 -+
5199 - #ifdef GRID_FIT_METRICS
5200 - static void
5201 - ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot,
5202 -@@ -571,8 +587,33 @@
5203 - FT_Bool autohint = FALSE;
5204 - FT_Module hinter;
5205 - TT_Face ttface = (TT_Face)face;
5206 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5207 -
5208 -+ int checked_use_various_tweaks_env = FALSE;
5209 -+ FT_Bool use_various_tweaks = FALSE;
5210 -
5211 -+ if ( !checked_use_various_tweaks_env )
5212 -+ {
5213 -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
5214 -+ if ( use_various_tweaks_env != NULL )
5215 -+ {
5216 -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 )
5217 -+ {
5218 -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE;
5219 -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE;
5220 -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE;
5221 -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE;
5222 -+ }
5223 -+ }
5224 -+ checked_use_various_tweaks_env = 1;
5225 -+ }
5226 -+
5227 -+ /* Force autohint if no tt instructions */
5228 -+ if ( use_various_tweaks &&
5229 -+ ttface->num_locations &&
5230 -+ ttface->max_profile.maxSizeOfInstructions == 0 )
5231 -+ load_flags |= FT_LOAD_FORCE_AUTOHINT;
5232 -+#endif
5233 - if ( !face || !face->size || !face->glyph )
5234 - return FT_Err_Invalid_Face_Handle;
5235 -
5236 -@@ -652,8 +693,18 @@
5237 - if ( autohint )
5238 - {
5239 - FT_AutoHinter_Service hinting;
5240 --
5241 --
5242 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5243 -+ if ( use_various_tweaks )
5244 -+ {
5245 -+ /* Force slight hinting over full hinting always */
5246 -+ load_flags &= ~FT_LOAD_TARGET_LCD;
5247 -+ load_flags &= ~FT_LOAD_TARGET_LCD_V;
5248 -+ load_flags &= ~FT_LOAD_TARGET_MONO;
5249 -+ load_flags &= ~FT_LOAD_TARGET_NORMAL;
5250 -+ load_flags |= FT_LOAD_TARGET_LIGHT;
5251 -+ /*printf("%d ", load_flags);*/
5252 -+ }
5253 -+#endif
5254 - /* try to load embedded bitmaps first if available */
5255 - /* */
5256 - /* XXX: This is really a temporary hack that should disappear */
5257 -@@ -691,6 +742,10 @@
5258 - }
5259 - else
5260 - {
5261 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5262 -+ char* c1 = "CUR_WIDTH";
5263 -+ char* c2 = "0";
5264 -+#endif
5265 - error = driver->clazz->load_glyph( slot,
5266 - face->size,
5267 - glyph_index,
5268 -@@ -698,6 +753,16 @@
5269 - if ( error )
5270 - goto Exit;
5271 -
5272 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5273 -+ setenv(c1, c2, 1);
5274 -+
5275 -+ {
5276 -+ /* fix for sdl_ttf */
5277 -+ FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
5278 -+ ft_glyphslot_enlarge_metrics( slot, mode );
5279 -+ }
5280 -+#endif
5281 -+
5282 - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
5283 - {
5284 - /* check that the loaded outline is correct */
5285 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftoutln.c freetype-work/src/base/ftoutln.c
5286 ---- freetype-subpixel/src/base/ftoutln.c 2012-06-14 00:35:58.000000000 -0500
5287 -+++ freetype-work/src/base/ftoutln.c 2012-06-15 16:19:12.645429337 -0500
5288 -@@ -897,7 +897,29 @@
5289 - FT_Vector v_prev, v_first, v_next, v_cur;
5290 - FT_Int c, n, first;
5291 - FT_Int orientation;
5292 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5293 -+ int checked_use_various_tweaks_env = 0;
5294 -+ FT_Bool use_various_tweaks = FALSE;
5295 -
5296 -+ if ( checked_use_various_tweaks_env == 0 )
5297 -+ {
5298 -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
5299 -+ if ( use_various_tweaks_env != NULL )
5300 -+ {
5301 -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 )
5302 -+ {
5303 -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE;
5304 -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE;
5305 -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE;
5306 -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE;
5307 -+ }
5308 -+ }
5309 -+ checked_use_various_tweaks_env = 1;
5310 -+ }
5311 -+
5312 -+ if ( use_various_tweaks )
5313 -+ ystrength = FT_PIX_FLOOR ( ystrength );
5314 -+#endif
5315 -
5316 - if ( !outline )
5317 - return FT_Err_Invalid_Argument;
5318 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/base/ftsynth.c freetype-work/src/base/ftsynth.c
5319 ---- freetype-subpixel/src/base/ftsynth.c 2012-06-14 23:26:45.000000000 -0500
5320 -+++ freetype-work/src/base/ftsynth.c 2012-06-15 16:36:20.612600325 -0500
5321 -@@ -88,7 +88,26 @@
5322 - FT_Face face = slot->face;
5323 - FT_Error error;
5324 - FT_Pos xstr, ystr;
5325 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5326 -+ int checked_use_various_tweaks_env = 0;
5327 -+ FT_Bool use_various_tweaks = FALSE;
5328 -
5329 -+ if ( checked_use_various_tweaks_env == 0 )
5330 -+ {
5331 -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
5332 -+ if ( use_various_tweaks_env != NULL )
5333 -+ {
5334 -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 )
5335 -+ {
5336 -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0) use_various_tweaks = TRUE;
5337 -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0) use_various_tweaks = TRUE;
5338 -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0) use_various_tweaks = TRUE;
5339 -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0) use_various_tweaks = TRUE;
5340 -+ }
5341 -+ }
5342 -+ checked_use_various_tweaks_env = 1;
5343 -+ }
5344 -+#endif
5345 -
5346 - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
5347 - slot->format != FT_GLYPH_FORMAT_BITMAP )
5348 -@@ -101,6 +120,11 @@
5349 -
5350 - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
5351 - {
5352 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5353 -+ if ( use_various_tweaks )
5354 -+ (void)FT_Outline_EmboldenXY( &slot->outline, xstr, FT_PIX_FLOOR( ystr ) );
5355 -+ else
5356 -+#endif
5357 - /* ignore error */
5358 - (void)FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
5359 - }
5360 -@@ -141,6 +165,9 @@
5361 -
5362 - slot->metrics.width += xstr;
5363 - slot->metrics.height += ystr;
5364 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5365 -+ /*if ( !use_various_tweaks ) */
5366 -+#endif
5367 - slot->metrics.horiAdvance += xstr;
5368 - slot->metrics.vertAdvance += ystr;
5369 -
5370 -diff -Nur -x '*~' -x '*.rej' -x '*.orig' -x '*.SUP' freetype-subpixel/src/smooth/ftsmooth.c freetype-work/src/smooth/ftsmooth.c
5371 ---- freetype-subpixel/src/smooth/ftsmooth.c 2012-06-14 00:35:58.000000000 -0500
5372 -+++ freetype-work/src/smooth/ftsmooth.c 2012-06-15 07:42:35.030819204 -0500
5373 -@@ -26,6 +26,16 @@
5374 -
5375 - #include "ftsmerrs.h"
5376 -
5377 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5378 -+#include <math.h>
5379 -+#include "../../include/freetype/ftbitmap.h"
5380 -+#include "strings.h"
5381 -+#include "../autofit/aflatin.h"
5382 -+#include "../../include/freetype/ftoutln.h"
5383 -+
5384 -+#define verbose FALSE
5385 -+#define STVALUES if (verbose) printf ("scale:%f translate:%ld ", *scale_value, *translate_value);
5386 -+#endif
5387 -
5388 - /* initialize renderer -- init its raster */
5389 - static FT_Error
5390 -@@ -34,65 +44,2822 @@
5391 - FT_Library library = FT_MODULE_LIBRARY( render );
5392 -
5393 -
5394 -- render->clazz->raster_class->raster_reset( render->raster,
5395 -- library->raster_pool,
5396 -- library->raster_pool_size );
5397 -+ render->clazz->raster_class->raster_reset( render->raster,
5398 -+ library->raster_pool,
5399 -+ library->raster_pool_size );
5400 -+
5401 -+ return 0;
5402 -+ }
5403 -+
5404 -+
5405 -+ /* sets render-specific mode */
5406 -+ static FT_Error
5407 -+ ft_smooth_set_mode( FT_Renderer render,
5408 -+ FT_ULong mode_tag,
5409 -+ FT_Pointer data )
5410 -+ {
5411 -+ /* we simply pass it to the raster */
5412 -+ return render->clazz->raster_class->raster_set_mode( render->raster,
5413 -+ mode_tag,
5414 -+ data );
5415 -+ }
5416 -+
5417 -+ /* transform a given glyph image */
5418 -+ static FT_Error
5419 -+ ft_smooth_transform( FT_Renderer render,
5420 -+ FT_GlyphSlot slot,
5421 -+ const FT_Matrix* matrix,
5422 -+ const FT_Vector* delta )
5423 -+ {
5424 -+ FT_Error error = Smooth_Err_Ok;
5425 -+
5426 -+
5427 -+ if ( slot->format != render->glyph_format )
5428 -+ {
5429 -+ error = Smooth_Err_Invalid_Argument;
5430 -+ goto Exit;
5431 -+ }
5432 -+
5433 -+ if ( matrix )
5434 -+ FT_Outline_Transform( &slot->outline, matrix );
5435 -+
5436 -+ if ( delta )
5437 -+ FT_Outline_Translate( &slot->outline, delta->x, delta->y );
5438 -+
5439 -+ Exit:
5440 -+ return error;
5441 -+ }
5442 -+
5443 -+
5444 -+ /* return the glyph's control box */
5445 -+ static void
5446 -+ ft_smooth_get_cbox( FT_Renderer render,
5447 -+ FT_GlyphSlot slot,
5448 -+ FT_BBox* cbox )
5449 -+ {
5450 -+ FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
5451 -+
5452 -+ if ( slot->format == render->glyph_format )
5453 -+ FT_Outline_Get_CBox( &slot->outline, cbox );
5454 -+ }
5455 -+
5456 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
5457 -+ static FT_Fixed FT_FixedFromFloat(float f)
5458 -+ {
5459 -+ short value = f;
5460 -+ unsigned short fract = (f - value) * 0xFFFF;
5461 -+ return (FT_Fixed)((long)value << 16 | (unsigned long)fract);
5462 -+ }
5463 -+
5464 -+
5465 -+ /* ChromeOS sharpening algorithm */
5466 -+ /* soften the sub-pixel anti-aliasing and sharpen */
5467 -+ static void
5468 -+ _ft_lcd_chromeos_sharpen( FT_Bitmap* bitmap,
5469 -+ FT_Render_Mode mode,
5470 -+ FT_Byte cutoff,
5471 -+ double gamma_value )
5472 -+ {
5473 -+ static FT_Bool initialized_gamma = FALSE;
5474 -+ static unsigned short gamma_ramp[256];
5475 -+ FT_UInt width = (FT_UInt)bitmap->width;
5476 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5477 -+ int ii;
5478 -+
5479 -+ if (!initialized_gamma)
5480 -+ {
5481 -+ initialized_gamma = TRUE;
5482 -+ /* linear to voltage */
5483 -+ for ( ii = 0; ii < 256; ii++ )
5484 -+ {
5485 -+ gamma_ramp[ii] = (unsigned char)
5486 -+ ( pow( (double)ii/255.0, gamma_value ) * 255.0f );
5487 -+ if (gamma_ramp[ii] < cutoff) {
5488 -+ gamma_ramp[ii] = 0;
5489 -+ }
5490 -+ }
5491 -+ }
5492 -+
5493 -+ /* horizontal in-place sub-pixel sharpening filter */
5494 -+ if ( mode == FT_RENDER_MODE_LCD)
5495 -+ {
5496 -+ FT_Byte* line = bitmap->buffer;
5497 -+ for ( ; height > 0; height--, line += bitmap->pitch )
5498 -+ {
5499 -+ FT_UInt xx;
5500 -+ for ( xx = 0; xx < width; xx++ )
5501 -+ {
5502 -+ line[xx] = gamma_ramp[line[xx]];
5503 -+ }
5504 -+ }
5505 -+ }
5506 -+ }
5507 -+
5508 -+ /* simple linear scale to handle various sliding values */
5509 -+ float
5510 -+ sliding_scale ( int min_value,
5511 -+ int max_value,
5512 -+ float min_amount,
5513 -+ float max_amount,
5514 -+ int cur_value )
5515 -+ {
5516 -+
5517 -+ float m = (min_amount - max_amount) / (float)(min_value - max_value);
5518 -+ float result = (((float)cur_value * m) + (max_amount - max_value * m)) ;
5519 -+
5520 -+ if (min_amount < max_amount)
5521 -+ {
5522 -+ if (result < min_amount) return min_amount;
5523 -+ if (result > max_amount) return max_amount;
5524 -+ }
5525 -+ else
5526 -+ {
5527 -+ if (result < max_amount) return max_amount;
5528 -+ if (result > min_amount) return min_amount;
5529 -+ }
5530 -+
5531 -+ return result;
5532 -+ }
5533 -+
5534 -+
5535 -+ /* brightness and contrast adjustment on the bitmap */
5536 -+ static FT_Bool
5537 -+ _ft_bitmap_bc ( FT_Bitmap* bitmap,
5538 -+ float brightness,
5539 -+ float contrast )
5540 -+ {
5541 -+
5542 -+ FT_UInt width = (FT_UInt)bitmap->width;
5543 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5544 -+ FT_Byte* line = bitmap->buffer;
5545 -+ FT_UInt xx;
5546 -+
5547 -+ if ( brightness == 0 && contrast == 0 ) return FALSE;
5548 -+
5549 -+ for (height = (FT_UInt)bitmap->rows;
5550 -+ height > 0;
5551 -+ height--, line += bitmap->pitch )
5552 -+ {
5553 -+ for ( xx = 0; xx < width - 1; xx += 1 )
5554 -+ {
5555 -+ if ( line[xx] > 0)
5556 -+ {
5557 -+ float value = (float)(255 - line[xx]) / 256.0;
5558 -+ FT_Int result = 0;
5559 -+
5560 -+ if (brightness < 0.0) value = value * ( 1.0 + brightness);
5561 -+ else value = value + ((1.0 - value) * brightness);
5562 -+ value = (value - 0.5) * (tan ((contrast + 1.0) * 3.141592/4.0) ) + 0.5;
5563 -+
5564 -+ result = (FT_Int)(255.0 - (value) * 256.0);
5565 -+
5566 -+ if (result < 0) result = 0;
5567 -+ if (result > 255) result = 255;
5568 -+
5569 -+ line[xx] = result;
5570 -+ }
5571 -+ }
5572 -+ }
5573 -+ return TRUE;
5574 -+ }
5575 -+
5576 -+
5577 -+ /* Filter to mimic Windows-style sharpening */
5578 -+ /* Determined via 100% experimentation. */
5579 -+ static void
5580 -+ _ft_lcd_windows_sharpen( FT_Bitmap* bitmap,
5581 -+ FT_Render_Mode mode,
5582 -+ FT_UInt strength,
5583 -+ FT_Library library )
5584 -+ {
5585 -+
5586 -+ FT_UInt width = (FT_UInt)bitmap->width;
5587 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5588 -+
5589 -+ FT_Byte* new_line;
5590 -+ FT_Byte* line = bitmap->buffer;
5591 -+
5592 -+ FT_Bitmap new_bitmap;
5593 -+
5594 -+ FT_Bitmap_New(&new_bitmap);
5595 -+
5596 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
5597 -+ new_line = (&new_bitmap)->buffer;
5598 -+
5599 -+ if (strength > 0)
5600 -+ for (height = (FT_UInt)bitmap->rows;
5601 -+ height > 0;
5602 -+ height--, line += bitmap->pitch, new_line += bitmap->pitch )
5603 -+ {
5604 -+ FT_UInt xx, threshold = 128;
5605 -+ FT_Byte* prevline = line - bitmap->pitch;
5606 -+ FT_Byte* nextline = line + bitmap->pitch;
5607 -+
5608 -+ FT_Byte* new_prevline = new_line - bitmap->pitch;
5609 -+ FT_Byte* new_nextline = new_line + bitmap->pitch;
5610 -+
5611 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5612 -+ {
5613 -+ /* subpixel grid sp11 sp21 sp31 */
5614 -+ /* where sp22 is sp12 sp22 sp32 */
5615 -+ /* current subpixel. sp13 sp23 sp33 */
5616 -+
5617 -+ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff,
5618 -+ prevdiff, nextdiff, sp11, sp21, sp31, sp12, sp22, sp32,
5619 -+ sp13, sp23, sp33;
5620 -+
5621 -+ sp12 = line [xx-1];
5622 -+ sp22 = line [xx];
5623 -+ sp32 = line [xx+1];
5624 -+
5625 -+ if (height == bitmap->rows)
5626 -+ {
5627 -+ prevtotal = sp11 = sp21 = sp31 = 0;
5628 -+ prevdiff = sp22;
5629 -+ lefttotal = sp12 + sp13;
5630 -+ righttotal = sp32 + sp33;
5631 -+ }
5632 -+ else
5633 -+ {
5634 -+ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1];
5635 -+ sp11 = prevline [xx-1];
5636 -+ sp21 = prevline [xx];
5637 -+ sp31 = prevline [xx+1];
5638 -+ prevdiff = sp22 - sp21;
5639 -+ lefttotal = sp11 + sp12 + sp13;
5640 -+ righttotal = sp31 + sp32 + sp33;
5641 -+ }
5642 -+
5643 -+
5644 -+ if (height == 1)
5645 -+ {
5646 -+ nexttotal = sp13 = sp23 = sp33 = 0;
5647 -+ nextdiff = sp22;
5648 -+ lefttotal = sp11 + sp12;
5649 -+ righttotal = sp31 + sp32;
5650 -+ }
5651 -+ else
5652 -+ {
5653 -+ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1];
5654 -+ sp13 = nextline [xx-1];
5655 -+ sp23 = nextline [xx];
5656 -+ sp33 = nextline [xx+1];
5657 -+ nextdiff = sp23 - sp22;
5658 -+ lefttotal = sp11 + sp12 + sp13;
5659 -+ righttotal = sp31 + sp32 + sp33;
5660 -+ }
5661 -+
5662 -+ sidesdiff = lefttotal - righttotal;
5663 -+ if (sidesdiff < 0) sidesdiff *= -1;
5664 -+ if (prevdiff < 0) prevdiff *= -1;
5665 -+ if (nextdiff < 0) nextdiff *= -1;
5666 -+
5667 -+ /* if the current pixel is less than threshold, and greater than 0 */
5668 -+ if ( sp22 <= threshold && sp22 > 0 )
5669 -+ {
5670 -+ /* A pixel is horizontally isolated if: */
5671 -+ /* 1: All upper adjecent pixels are >= threshold */
5672 -+ if ( prevtotal >= nexttotal && abs (sp11 - sp12) > 5 && abs (sp21 - sp22) > 5 && abs (sp31 - sp32) > 5 /* not a vert stem end */
5673 -+ && sp11 >= threshold
5674 -+ && sp21 >= threshold
5675 -+ && sp31 >= threshold && abs (sp23 - sp22) > 15 /* not on a vert stem */
5676 -+ )
5677 -+ {
5678 -+ /* darken upper adjacent subpixel; lighten current */
5679 -+ if (height != (FT_UInt)bitmap->rows) new_prevline[xx] += ((255 - new_prevline[xx]) * strength) / 100 ;
5680 -+ new_line[xx] -= (new_line[xx] * strength) / 100;
5681 -+
5682 -+ if (height != 1 && height != (FT_UInt)bitmap->rows) if (new_nextline[xx] > 155 + (100 - strength)) new_prevline[xx] = 255;
5683 -+
5684 -+ }
5685 -+ else if ( nexttotal > prevtotal && abs (sp13 - sp12) > 5 && abs (sp23 - sp22) > 5 && abs (sp33 - sp32) > 5
5686 -+ /* 2: All lower adjecent pixels are >= threshold */
5687 -+ && sp13 >= threshold
5688 -+ && sp23 >= threshold
5689 -+ && sp33 >= threshold && abs (sp22 - sp21) > 15
5690 -+ )
5691 -+ {
5692 -+ /* darken lower adjacent subpixel; lighten current */
5693 -+ if (height != 1) new_nextline[xx] += (255 - new_nextline[xx]) * strength / 100 ;
5694 -+ new_line[xx] -= (new_line[xx] * strength) / 100;
5695 -+
5696 -+ if (height != 1) if (new_nextline[xx] > 155 + (100 - strength)) new_nextline[xx] = 255;
5697 -+
5698 -+ }
5699 -+ }
5700 -+ else if ( sp22 > threshold && sp22 < 255 )
5701 -+ {
5702 -+ if ( sp11 <= threshold && abs (sp13 - sp12) > 5 && abs (sp23 - sp22) > 5 && abs (sp33 - sp32) > 5
5703 -+ && sp21 <= threshold
5704 -+ && sp31 <= threshold
5705 -+ && prevtotal <= nexttotal && abs (sp22 - sp21) > 15
5706 -+ )
5707 -+ {
5708 -+ /* bring this subpixel 1/3 of the way to 255 at 100% strength */
5709 -+ new_line[xx] += (strength * (255 - new_line[xx]))/100 ;
5710 -+ if (height != (FT_UInt)bitmap->rows) new_prevline[xx] -= (new_prevline[xx] * strength) / 300;
5711 -+ }
5712 -+ else if (
5713 -+ sp13 <= threshold && abs (sp11 - sp12) > 5 && abs (sp21 - sp22) > 5 && abs (sp31 - sp32) > 5
5714 -+ && sp23 <= threshold
5715 -+ && sp33 <= threshold &&
5716 -+ nexttotal < prevtotal && abs (sp23 - sp22) > 15
5717 -+
5718 -+ )
5719 -+ {
5720 -+ new_line[xx] += (strength * (255 - new_line[xx]))/100 ;
5721 -+ if (height != 1) new_nextline[xx] -= (new_nextline[xx] * strength) / 300;
5722 -+ }
5723 -+ }
5724 -+ }
5725 -+ }
5726 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
5727 -+ FT_Bitmap_Done(library, &new_bitmap);
5728 -+ }
5729 -+
5730 -+
5731 -+ static void
5732 -+ _ft_lcd_darken_x ( FT_Bitmap* bitmap,
5733 -+ FT_Render_Mode mode,
5734 -+ FT_UInt strength,
5735 -+ FT_Library library )
5736 -+ {
5737 -+
5738 -+ FT_UInt width = (FT_UInt)bitmap->width;
5739 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5740 -+
5741 -+ FT_Byte* new_line;
5742 -+ FT_Byte* line = bitmap->buffer;
5743 -+
5744 -+ FT_Bitmap new_bitmap;
5745 -+
5746 -+ int factor1,factor2;
5747 -+ int bias = 0;
5748 -+
5749 -+ FT_Bitmap_New(&new_bitmap);
5750 -+
5751 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
5752 -+ new_line = (&new_bitmap)->buffer;
5753 -+
5754 -+ if (strength > 0)
5755 -+ for (height = (FT_UInt)bitmap->rows;
5756 -+ height > 0;
5757 -+ height--, line += bitmap->pitch, new_line += bitmap->pitch )
5758 -+ {
5759 -+ FT_UInt xx;
5760 -+ FT_Byte* prevline = line - bitmap->pitch;
5761 -+ FT_Byte* nextline = line + bitmap->pitch;
5762 -+
5763 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5764 -+ {
5765 -+ /* subpixel grid sp11 sp21 sp31 */
5766 -+ /* where sp22 is sp12 sp22 sp32 */
5767 -+ /* current subpixel. sp13 sp23 sp33 */
5768 -+
5769 -+ FT_Int sp21, sp12, sp22, sp32, sp23;
5770 -+
5771 -+ sp12 = line [xx-1];
5772 -+ sp22 = line [xx];
5773 -+ sp32 = line [xx+1];
5774 -+
5775 -+ if (height == bitmap->rows)
5776 -+ {
5777 -+ sp21 = 0;
5778 -+ }
5779 -+ else
5780 -+ {
5781 -+ sp21 = prevline [xx];
5782 -+ }
5783 -+
5784 -+ if (height == 1)
5785 -+ {
5786 -+ sp23 = 0;
5787 -+
5788 -+ }
5789 -+ else
5790 -+ {
5791 -+ sp23 = nextline [xx];
5792 -+ }
5793 -+
5794 -+ /* darken subpixel if neighbor above and below are much less than */
5795 -+ /* safer but less effective */
5796 -+ factor1 = 5;
5797 -+ factor2 = 5;
5798 -+
5799 -+ /* make matches in the middle of glyph slightly darker */
5800 -+ /*if (height > 1 && height < (FT_UInt)bitmap->rows) bias = 1;*/
5801 -+
5802 -+ if ( sp22 > factor1 * sp21 && sp22 > factor1 * sp23 && sp22 > factor2 && sp12 > 16 && sp32 > 16 )
5803 -+ if (new_line[xx] < (strength * 255) / 100 )
5804 -+ new_line[xx] = (strength * 255) / 100 + bias * (255 - (strength * 255) / 100) / 3;
5805 -+
5806 -+ }
5807 -+ }
5808 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
5809 -+ FT_Bitmap_Done(library, &new_bitmap);
5810 -+ }
5811 -+
5812 -+
5813 -+ static void
5814 -+ _ft_lcd_darken_y ( FT_Bitmap* bitmap,
5815 -+ FT_Render_Mode mode,
5816 -+ FT_UInt strength,
5817 -+ FT_Library library )
5818 -+ {
5819 -+
5820 -+ FT_UInt width = (FT_UInt)bitmap->width;
5821 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5822 -+
5823 -+ FT_Byte* new_line;
5824 -+ FT_Byte* line = bitmap->buffer;
5825 -+
5826 -+ FT_Bitmap new_bitmap;
5827 -+
5828 -+ FT_Bitmap_New(&new_bitmap);
5829 -+
5830 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
5831 -+ new_line = (&new_bitmap)->buffer;
5832 -+
5833 -+ if (strength > 0)
5834 -+ for (height = (FT_UInt)bitmap->rows;
5835 -+ height > 0;
5836 -+ height--, line += bitmap->pitch, new_line += bitmap->pitch )
5837 -+ {
5838 -+
5839 -+ FT_UInt xx;
5840 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5841 -+ {
5842 -+ if (line[xx] > line[xx-1] && line[xx] > line[xx+1])
5843 -+ {
5844 -+ if (new_line[xx] > 0) new_line[xx] += (strength * (255 - new_line[xx])) / 100;
5845 -+ new_line[xx-1] += (strength * (255 - line[xx-1])) / 100;
5846 -+ new_line[xx+1] += (strength * (255 - line[xx+1])) / 100;
5847 -+ }
5848 -+ }
5849 -+ }
5850 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
5851 -+ FT_Bitmap_Done(library, &new_bitmap);
5852 -+ }
5853 -+
5854 -+
5855 -+ static void
5856 -+ _ft_bitmap_cap ( FT_Bitmap* bitmap,
5857 -+ FT_UInt strength,
5858 -+ FT_Library library )
5859 -+ {
5860 -+
5861 -+ FT_UInt width = (FT_UInt)bitmap->width;
5862 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5863 -+
5864 -+ FT_Byte* new_line;
5865 -+ FT_Byte* line = bitmap->buffer;
5866 -+
5867 -+ FT_UInt cur_value = 0;
5868 -+
5869 -+ FT_Bitmap new_bitmap;
5870 -+
5871 -+ FT_Bitmap_New(&new_bitmap);
5872 -+
5873 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
5874 -+ new_line = (&new_bitmap)->buffer;
5875 -+
5876 -+ if (strength > 0)
5877 -+ for (height = (FT_UInt)bitmap->rows;
5878 -+ height > 0;
5879 -+ height--, line += bitmap->pitch, new_line += bitmap->pitch )
5880 -+ {
5881 -+
5882 -+ FT_UInt xx;
5883 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5884 -+ {
5885 -+ cur_value = (new_line[xx-1] + new_line[xx] + new_line[xx+1]) / 3;
5886 -+ if (cur_value > (strength * 255) / 100 )
5887 -+ {
5888 -+ FT_UInt new_factor = (strength * 255) / 100;
5889 -+ new_line[xx] = (new_line[xx] * new_factor) / cur_value;
5890 -+ new_line[xx+1] = (new_line[xx+1] * new_factor) / cur_value;
5891 -+ new_line[xx-1] = (new_line[xx-1] * new_factor) / cur_value;
5892 -+ }
5893 -+ }
5894 -+ }
5895 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
5896 -+ FT_Bitmap_Done(library, &new_bitmap);
5897 -+ }
5898 -+
5899 -+
5900 -+ int
5901 -+ gamma2 ( int val, float value )
5902 -+ {
5903 -+ return 256 * (1.0 - pow((1.0 - (float)val/ 256.0) , 1.0/value));
5904 -+ }
5905 -+
5906 -+
5907 -+
5908 -+ static void
5909 -+ _ft_bitmap_embolden ( FT_Bitmap* bitmap,
5910 -+ FT_UInt strength,
5911 -+ FT_Library library )
5912 -+ {
5913 -+
5914 -+ FT_UInt width = (FT_UInt)bitmap->width;
5915 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5916 -+
5917 -+ FT_Byte* new_line;
5918 -+ FT_Byte* line = bitmap->buffer;
5919 -+ FT_Bitmap new_bitmap;
5920 -+ FT_UInt xx;
5921 -+
5922 -+ FT_Bitmap_New(&new_bitmap);
5923 -+
5924 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
5925 -+
5926 -+ new_line = (&new_bitmap)->buffer;
5927 -+
5928 -+ if (strength > 0)
5929 -+ for (height = (FT_UInt)bitmap->rows;
5930 -+ height > 0;
5931 -+ height--, line += bitmap->pitch, new_line += bitmap->pitch )
5932 -+ {
5933 -+
5934 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5935 -+ {
5936 -+
5937 -+ FT_Int new_value = 0;
5938 -+
5939 -+ new_value = (strength * line [xx-1]) / 100 + gamma2(line [xx], .75) + (strength * line [xx+1]) / 100;
5940 -+ if (new_value > 255) new_value = 255;
5941 -+
5942 -+ new_line[xx] = new_value;
5943 -+
5944 -+ }
5945 -+ }
5946 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
5947 -+ FT_Bitmap_Done(library, &new_bitmap);
5948 -+ }
5949 -+
5950 -+
5951 -+
5952 -+ static void
5953 -+ _ft_bitmap_gamma ( FT_Bitmap* bitmap,
5954 -+ float strength )
5955 -+ {
5956 -+
5957 -+ FT_UInt width = (FT_UInt)bitmap->width;
5958 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5959 -+
5960 -+ FT_Byte* line = bitmap->buffer;
5961 -+
5962 -+ FT_UInt xx;
5963 -+
5964 -+ if (strength > 0)
5965 -+ for (height = (FT_UInt)bitmap->rows;
5966 -+ height > 0;
5967 -+ height--, line += bitmap->pitch )
5968 -+ {
5969 -+
5970 -+ for ( xx = 1; xx < width - 1; xx += 1 )
5971 -+ {
5972 -+ if (abs(line[xx-1] - line[xx]) < 20 || abs(line[xx+1] - line[xx]) < 20)
5973 -+ line [xx] = gamma2(line [xx], strength) ;
5974 -+
5975 -+ }
5976 -+
5977 -+ }
5978 -+ }
5979 -+
5980 -+
5981 -+ /* Fringe filter */
5982 -+ static void
5983 -+ _ft_lcd_fringe_filter ( FT_Bitmap* bitmap,
5984 -+ FT_Render_Mode mode,
5985 -+ FT_UInt strength,
5986 -+ FT_Library library )
5987 -+ {
5988 -+
5989 -+ FT_UInt width = (FT_UInt)bitmap->width;
5990 -+ FT_UInt height = (FT_UInt)bitmap->rows;
5991 -+ FT_Byte* new_line;
5992 -+ FT_Byte* line = bitmap->buffer;
5993 -+
5994 -+ FT_Bitmap new_bitmap;
5995 -+ FT_Bitmap_New(&new_bitmap);
5996 -+
5997 -+
5998 -+ line = bitmap->buffer;
5999 -+ FT_Bitmap_Copy(library, bitmap, &new_bitmap);
6000 -+ new_line = (&new_bitmap)->buffer;
6001 -+ for (height = (FT_UInt)bitmap->rows ; height > 0; height--, line += bitmap->pitch, new_line += bitmap->pitch )
6002 -+ {
6003 -+ /* Threshold set to 1/2 pixel intensity */
6004 -+ FT_UInt xx, threshold = 128;
6005 -+
6006 -+ /* Hack to make this work when bitmap is at first or last line */
6007 -+ FT_Int fudge = bitmap->pitch * (height == (FT_UInt)bitmap->rows);
6008 -+
6009 -+
6010 -+ FT_Byte* prevline = line - bitmap->pitch + fudge;
6011 -+ FT_Byte* nextline = line + bitmap->pitch;
6012 -+
6013 -+ for ( xx = 1; xx < width - 1; xx += 1 )
6014 -+ {
6015 -+ /* subpixel grid sp11 sp21 sp31 */
6016 -+ /* where sp22 is sp12 sp22 sp32 */
6017 -+ /* current subpixel. sp13 sp23 sp33 */
6018 -+
6019 -+ FT_Int prevtotal, nexttotal, lefttotal, righttotal, sidesdiff,
6020 -+ leftdiff, rightdiff, prevdiff, nextdiff, sp11, sp21, sp31,
6021 -+ sp12, sp22, sp32, sp13, sp23, sp33;
6022 -+
6023 -+ sp12 = line [xx-1];
6024 -+ sp22 = line [xx];
6025 -+ sp32 = line [xx+1];
6026 -+
6027 -+ /* if at max height fake out some values */
6028 -+ if (height == (FT_UInt)bitmap->rows)
6029 -+ {
6030 -+ prevtotal = sp11 = sp21 = sp31 = 0;
6031 -+ prevdiff = sp22;
6032 -+ lefttotal = sp12 + sp13;
6033 -+ righttotal = sp32 + sp33;
6034 -+ }
6035 -+ else
6036 -+ {
6037 -+ prevtotal = prevline[xx-1] + prevline[xx] + prevline[xx+1];
6038 -+ sp11 = prevline [xx-1];
6039 -+ sp21 = prevline [xx];
6040 -+ sp31 = prevline [xx+1];
6041 -+ prevdiff = sp22 - sp21;
6042 -+ lefttotal = sp11 + sp12 + sp13;
6043 -+ righttotal = sp31 + sp32 + sp33;
6044 -+ }
6045 -+
6046 -+ /* if at min height fake out some values */
6047 -+ if (height == 1)
6048 -+ {
6049 -+ nexttotal = sp13 = sp23 = sp33 = 0;
6050 -+ nextdiff = sp22;
6051 -+ lefttotal = sp11 + sp12;
6052 -+ righttotal = sp31 + sp32;
6053 -+ }
6054 -+ else
6055 -+ {
6056 -+ nexttotal = nextline[xx-1] + nextline[xx] + nextline[xx+1];
6057 -+ sp13 = nextline [xx-1];
6058 -+ sp23 = nextline [xx];
6059 -+ sp33 = nextline [xx+1];
6060 -+ nextdiff = sp23 - sp22;
6061 -+ lefttotal = sp11 + sp12 + sp13;
6062 -+ righttotal = sp31 + sp32 + sp33;
6063 -+ }
6064 -+
6065 -+ sidesdiff = lefttotal - righttotal;
6066 -+ leftdiff = sp22 - sp12;
6067 -+ rightdiff = sp32 - sp22;
6068 -+ if (sidesdiff < 0) sidesdiff *= -1;
6069 -+ if (prevdiff < 0) prevdiff *= -1;
6070 -+ if (nextdiff < 0) nextdiff *= -1;
6071 -+ if (leftdiff < 0) leftdiff *= -1;
6072 -+ if (rightdiff < 0) rightdiff *= -1;
6073 -+
6074 -+ /* if the current subpixel is less than threshold, and varies only
6075 -+ slightly to left or right, lighten it */
6076 -+ if ( sp22 <= threshold && sp22 > 0 && (leftdiff < 10 || rightdiff < 10 ) )
6077 -+ {
6078 -+ /* A pixel is horizontally isolated if: */
6079 -+ /* 1: All upper adjecent subpixels are >= threshold and all lower
6080 -+ adjacent ones are essentially white */
6081 -+ if ( prevtotal >= nexttotal
6082 -+ && sp11 >= threshold
6083 -+ && sp21 >= threshold
6084 -+ && sp31 >= threshold
6085 -+ && sp13 < 2
6086 -+ && sp23 < 2
6087 -+ && sp33 < 2
6088 -+ )
6089 -+
6090 -+ {
6091 -+ new_line[xx] -= (new_line[xx] * strength) / 100;
6092 -+ if (leftdiff < 10) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */
6093 -+ if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */
6094 -+ }
6095 -+ else if ( nexttotal > prevtotal
6096 -+ /* 2: the inverse of above */
6097 -+ && sp13 >= threshold
6098 -+ && sp23 >= threshold
6099 -+ && sp33 >= threshold
6100 -+ && sp11 < 2
6101 -+ && sp21 < 2
6102 -+ && sp31 < 2
6103 -+ )
6104 -+ {
6105 -+ new_line[xx] -= (new_line[xx] * strength) / 100;
6106 -+ if (leftdiff < 10) new_line[xx-1] -= (new_line[xx-1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT - keep going left until 255? */
6107 -+ if (rightdiff < 10) new_line[xx+1] -= (new_line[xx+1] * strength) / 200; /* OPPORTUNITY FOR IMPROVEMENT */
6108 -+ }
6109 -+ }
6110 -+ /* otherwise if the current subpixel is more than threshold, and varies
6111 -+ slightly to left or right, darken it */
6112 -+ else if ( sp22 > threshold && sp22 < 255 && (leftdiff < 10 || rightdiff < 10 ) )
6113 -+ {
6114 -+ if ( sp11 <= 2
6115 -+ && sp21 <= 2
6116 -+ && sp31 <= 2
6117 -+ && sp13 >= threshold
6118 -+ && sp23 >= threshold
6119 -+ && sp33 >= threshold
6120 -+ &&
6121 -+ prevtotal < nexttotal
6122 -+ )
6123 -+
6124 -+ {
6125 -+ new_line[xx] += ((255 - new_line[xx]) * strength) / 100;
6126 -+ }
6127 -+ else if (
6128 -+ sp13 <= 2
6129 -+ && sp23 <= 2
6130 -+ && sp33 <= 2 &&
6131 -+ nexttotal < prevtotal
6132 -+ && sp11 >= threshold
6133 -+ && sp21 >= threshold
6134 -+ && sp31 >= threshold
6135 -+
6136 -+ )
6137 -+ {
6138 -+ new_line[xx] += ((255 - new_line[xx]) * strength) / 100;
6139 -+ }
6140 -+ }
6141 -+ }
6142 -+ }
6143 -+ FT_Bitmap_Copy(library, &new_bitmap, bitmap);
6144 -+ FT_Bitmap_Done(library, &new_bitmap);
6145 -+ }
6146 -+
6147 -+
6148 -+ /* Grayscale filter */
6149 -+ static void
6150 -+ _ft_lcd_grayscale_filter ( FT_Bitmap* bitmap,
6151 -+ FT_Render_Mode mode,
6152 -+ FT_UInt strength,
6153 -+ FT_Library library )
6154 -+ {
6155 -+
6156 -+ FT_UInt width = (FT_UInt)bitmap->width;
6157 -+ FT_UInt height = (FT_UInt)bitmap->rows;
6158 -+ FT_Byte* line = bitmap->buffer;
6159 -+
6160 -+ for (height = (FT_UInt)bitmap->rows; height > 0; height--, line += bitmap->pitch )
6161 -+ {
6162 -+ FT_UInt xx;
6163 -+ for ( xx = 0; xx < width - 1; xx += 3 )
6164 -+ {
6165 -+ FT_UInt total = line [xx] + line [xx + 1] + line [xx + 2];
6166 -+ line[xx] = ( (100-strength) * line[xx] + strength * (total / 3) ) / 100;
6167 -+ line[xx+1] = ( (100-strength) * line[xx+1] + strength * (total / 3) ) / 100;
6168 -+ line[xx+2] = ( (100-strength) * line[xx+2] + strength * (total / 3) ) / 100;
6169 -+ }
6170 -+ }
6171 -+ }
6172 -+
6173 -+
6174 -+
6175 -+ /*************************************************************************/
6176 -+ /* */
6177 -+ /* */
6178 -+ /* */
6179 -+ /* */
6180 -+ /* */
6181 -+ /* */
6182 -+
6183 -+
6184 -+ typedef struct SA_Rule_
6185 -+ {
6186 -+ const char family[32];
6187 -+ const int ppem[5];
6188 -+ } SA_Rule;
6189 -+
6190 -+#define STEM_WIDTH_2_PPEM 18
6191 -+#define MAX_PPEM 100
6192 -+
6193 -+
6194 -+
6195 -+/* "Font name", {ppem where stem width becomes 1,
6196 -+ * ppem where stem width becomes 2... etc.} */
6197 -+/* 100 means auto-calculate */
6198 -+#define SNAPPING_STEM_WIDTHS_RULES_SIZE 21
6199 -+ SA_Rule SNAPPING_STEM_WIDTHS_Rules
6200 -+ [SNAPPING_STEM_WIDTHS_RULES_SIZE] =
6201 -+ {
6202 -+ { "Andale Mono", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6203 -+ { "Arial Narrow", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6204 -+ { "Calibri", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6205 -+ { "Cantarell", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6206 -+ { "Century Gothic", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6207 -+ { "Comfortaa", {10, 19, 22, MAX_PPEM, MAX_PPEM} },
6208 -+ { "Consolas", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6209 -+ { "Corbel", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6210 -+ { "Futura", {10, 14, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6211 -+ { "Gill Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6212 -+ { "Helvetica CY", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6213 -+ { "Inconsolata", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6214 -+ { "Liberation Sans Narrow", {10, 22, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6215 -+ { "Liberation Sans", {10, 19, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6216 -+ { "Lucida Grande", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6217 -+ { "Lucida Sans Unicode", {10, 16, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6218 -+ { "Luxi Sans", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6219 -+ { "Open Sans", {10, 20, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6220 -+ { "Rokkitt", {10, 21, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6221 -+ { "Segoe UI", {10, 23, MAX_PPEM, MAX_PPEM, MAX_PPEM} },
6222 -+ { "Trebuchet MS", {10, 17, STEM_WIDTH_2_PPEM, MAX_PPEM, MAX_PPEM} },
6223 -+ };
6224 -+
6225 -+
6226 -+/* "Font name", {ppem, scale_up=1|scale_down=0} */
6227 -+#define SNAPPING_STEM_SCALING_RULES_SIZE 31
6228 -+ SA_Rule SNAPPING_STEM_SCALING_Rules
6229 -+ [SNAPPING_STEM_SCALING_RULES_SIZE] =
6230 -+ {
6231 -+ { "Andale Mono", {11, 1,} },
6232 -+ { "Bitstream Vera Sans", {12, 1,} },
6233 -+ { "Calibri", {15, 1,} },
6234 -+ { "Calibri", {17, 1,} },
6235 -+ { "Calibri", {18, 1,} },
6236 -+ { "Candara", {14, 1,} },
6237 -+ { "Candara", {17, 1,} },
6238 -+ { "Canwell", {13, 0,} },
6239 -+ { "Comfortaa", {11, 0,} },
6240 -+ { "Consolas", {11, 1,} },
6241 -+ { "DejaVu Sans", {12, 1,} },
6242 -+ { "Freesans", {16, 0,} },
6243 -+ { "Freeserif", {13, 1,} },
6244 -+ { "Freeserif", {17, 1,} },
6245 -+ { "Inconsolata", {12, 1,} },
6246 -+ { "Inconsolata", {15, 1,} },
6247 -+ { "Lucida Grande", {13, 1,} },
6248 -+ { "Myriad Pro", {14, 1,} },
6249 -+ { "Myriad Pro", {17, 1,} },
6250 -+ { "Nina", {11, 0,} },
6251 -+ { "Nina", {12, 0,} },
6252 -+ { "Nina", {13, 0,} },
6253 -+ { "Optima", {17, 1,} },
6254 -+ { "Raleway", {15, 0,} },
6255 -+ { "Samba", {11, 0,} },
6256 -+ { "Times New Roman", {17, 1,} },
6257 -+ { "Trebuchet MS", {17, 0,} },
6258 -+ { "Trebuchet MS", {13, 0,} },
6259 -+ { "Trebuchet MS", {20, 1,} },
6260 -+ { "Verdana", {12, 1,} },
6261 -+ { "Verdana", {15, 1,} },
6262 -+ };
6263 -+
6264 -+
6265 -+/* "Font name", {ppem, scale_up=1|scale_down=0} */
6266 -+#define SNAPPING_M_RULES_SIZE 9
6267 -+ SA_Rule SNAPPING_M_Rules
6268 -+ [SNAPPING_M_RULES_SIZE] =
6269 -+ {
6270 -+ { "Courier New", {13, 1,} },
6271 -+ { "Courier New", {14, 1,} },
6272 -+ { "Courier", {13, 1,} },
6273 -+ { "Courier", {14, 1,} },
6274 -+ { "Droid Sans Mono", {12, 0,} },
6275 -+ { "Bitstream Vera Sans", {12, 0,} },
6276 -+ { "DejaVu Sans", {12, 0,} },
6277 -+ { "Essential PragmataPro", {13, 0,} },
6278 -+ { "Essential PragmataPro", {14, 0,} },
6279 -+ };
6280 -+
6281 -+
6282 -+/* "Font name", {ppem, ppem} */
6283 -+#define SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE 1
6284 -+ SA_Rule SNAPPING_SYNTHESIZE_STEMS_Rules
6285 -+ [SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE] =
6286 -+ {
6287 -+ { "---", {13, 13,} },
6288 -+ };
6289 -+
6290 -+
6291 -+/* "Font name", {ppem, ppem} */
6292 -+#define SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE 1
6293 -+ SA_Rule SNAPPING_NO_BEARING_CORRECTION_Rules
6294 -+ [SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE] =
6295 -+ {
6296 -+ { "Times New Roman", {0, 100,} },
6297 -+ };
6298 -+
6299 -+
6300 -+/* "Font name", {ppem, ppem} */
6301 -+#define SNAPPING_EDGE_DETECTION_RULES_SIZE 8
6302 -+ SA_Rule SNAPPING_EDGE_DETECTION_Rules
6303 -+ [SNAPPING_EDGE_DETECTION_RULES_SIZE] =
6304 -+ {
6305 -+ { "Tahoma", {11, 11,} },
6306 -+ { "Courier New", {10, 12,} },
6307 -+ { "Arial", {11, 11,} },
6308 -+ { "Arial", {13, 13,} },
6309 -+ { "Liberation Sans", {11, 11,} },
6310 -+ { "FreeSans", {11, 11,} },
6311 -+ { "FreeSans", {13, 13,} },
6312 -+ { "Palatino Linotype", {0, 100,} },
6313 -+ };
6314 -+
6315 -+/* "Font name", {ppem, translate_value} */
6316 -+#define SNAPPING_STEM_TRANSLATING_RULES_SIZE 6
6317 -+ SA_Rule SNAPPING_STEM_TRANSLATING_Rules
6318 -+ [SNAPPING_STEM_TRANSLATING_RULES_SIZE] =
6319 -+ {
6320 -+ { "Arial", {11, 32,} },
6321 -+ { "Arial Unicode MS", {11, 32,} },
6322 -+ { "FreeSans", {11, 32,} },
6323 -+ { "Arimo", {11, 32,} },
6324 -+ { "Liberation Sans", {11, 32,} },
6325 -+ { "Tahoma", {11, 32,} },
6326 -+ };
6327 -+
6328 -+/* "Font name", {ppem, translate_value} */
6329 -+#define SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE 74
6330 -+ SA_Rule SNAPPING_STEM_TRANSLATING_ONLY_Rules
6331 -+ [SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE] =
6332 -+ {
6333 -+ { "Arial Unicode MS", {10, 16,} },
6334 -+ { "Arial Unicode MS", {8, 32,} },
6335 -+ { "Arial Unicode MS", {9, 32,} },
6336 -+ { "Arial", {10, 16,} },
6337 -+ { "Arial", {8, 32,} },
6338 -+ { "Arial", {9, 32,} },
6339 -+ { "Arial", {16, -24,} },
6340 -+ { "Arimo", {10, 8,} },
6341 -+ { "Arimo", {8, 32,} },
6342 -+ { "Arimo", {9, 32,} },
6343 -+ { "Bitstream Vera Sans", {8, 16,} },
6344 -+ { "Calibri", {10, 16,} },
6345 -+ { "Calibri", {15, 0,} },
6346 -+ { "Candara", {10, 16,} },
6347 -+ { "Cantarell", {11, 0} },
6348 -+ { "Cantarell", {12, 0} },
6349 -+ { "Consolas", {8, 32,} },
6350 -+ { "Consolas", {9, 32,} },
6351 -+ { "Corbel", {10, 16,} },
6352 -+ { "Courier", {13, 16,} },
6353 -+ { "Courier", {15, 0,} },
6354 -+ { "Dejavu Sans Mono", {7, 16,} },
6355 -+ { "Dejavu Sans Mono", {8, 32,} },
6356 -+ { "Dejavu Sans Mono", {9, 16,} },
6357 -+ { "Dejavu Sans", {8, 16,} },
6358 -+ { "Dejavu Sans", {15, -20,} },
6359 -+ { "Droid Sans", {8, 16,} },
6360 -+ { "Droid Sans", {9, 16,} },
6361 -+ { "Freesans", {10, 16,} },
6362 -+ { "Freesans", {9, 8,} },
6363 -+ { "Georgia", {13, 16,} },
6364 -+ { "Georgia", {14, 16,} },
6365 -+ { "Georgia", {15, 0,} },
6366 -+ { "Inconsolata", {10, 24,} },
6367 -+ { "Inconsolata", {9, 32,} },
6368 -+ { "Liberation Sans", {10, 8,} },
6369 -+ { "Liberation Sans", {8, 32,} },
6370 -+ { "Liberation Sans", {9, 32,} },
6371 -+ { "Lucida Grande", {13, 24,} },
6372 -+ { "Lucida Grande", {14, 24,} },
6373 -+ { "Lucida Grande", {8, 16,} },
6374 -+ { "Lucida Grande", {9, 16,} },
6375 -+ { "Lucida Sans Unicode", {13, 24,} },
6376 -+ { "Lucida Sans Unicode", {14, 24,} },
6377 -+ { "Lucida Sans Unicode", {8, 16,} },
6378 -+ { "Lucida Sans Unicode", {9, 16,} },
6379 -+ { "Microsoft Sans Serif", {10, 16,} },
6380 -+ { "Microsoft Sans Serif", {8, 32,} },
6381 -+ { "Microsoft Sans Serif", {9, 32,} },
6382 -+ { "Myriad Pro", {10, 16,} },
6383 -+ { "Myriad Pro", {11, 0,} },
6384 -+ { "Myriad Pro", {9, 16,} },
6385 -+ { "Open Sans", {10, 16,} },
6386 -+ { "Open Sans", {9, 16,} },
6387 -+ { "Optima", {10, 0} },
6388 -+ { "Optima", {11, 0} },
6389 -+ { "Optima", {12, 0} },
6390 -+ { "Segoe UI", {10, 0,} },
6391 -+ { "Segoe UI", {7, 32,} },
6392 -+ { "Segoe UI", {8, 16,} },
6393 -+ { "Segoe UI", {9, 24,} },
6394 -+ { "Tahoma", {7, 32,} },
6395 -+ { "Tahoma", {8, 32,} },
6396 -+ { "Tahoma", {9, 32,} },
6397 -+ { "Times New Roman", {17, 8,} },
6398 -+ { "Trebuchet MS", {10, 16,} },
6399 -+ { "Trebuchet MS", {11, 0,} },
6400 -+ { "Trebuchet MS", {8, 32,} },
6401 -+ { "Trebuchet MS", {9, 32,} },
6402 -+ { "Verdana", {8, 16,} },
6403 -+ { "Verdana", {15, 16,} },
6404 -+ { "Verdana", {14, 32,} },
6405 -+ { "Verdana", {18, 32,} },
6406 -+ { "Verdana", {19, 24,} },
6407 -+ };
6408 -+
6409 -+
6410 -+/* "Font name", {start ppem, end ppem} */
6411 -+#define ALWAYS_USE_100_RULES_SIZE 46
6412 -+ SA_Rule ALWAYS_USE_100_Rules
6413 -+ [ALWAYS_USE_100_RULES_SIZE] =
6414 -+ {
6415 -+ { "Andale Mono", {0, MAX_PPEM,} },
6416 -+ { "Arial Unicode MS", {0, MAX_PPEM,} },
6417 -+ { "Arial", {0, MAX_PPEM,} },
6418 -+ { "Arimo", {0, MAX_PPEM,} },
6419 -+ { "Bitstream Vera Sans Mono", {0, MAX_PPEM,} },
6420 -+ { "Bitstream Vera Sans", {10, 14,} },
6421 -+ { "Bitstream Vera Sans", {16, 17,} },
6422 -+ { "Calibri", {23, MAX_PPEM,} },
6423 -+ { "Consolas", {0, MAX_PPEM,} },
6424 -+ { "Courier New", {12, 12,} },
6425 -+ { "Courier", {0, MAX_PPEM,} },
6426 -+ { "Cousine", {0, MAX_PPEM,} },
6427 -+ { "DejaVu Sans Mono", {0, MAX_PPEM,} },
6428 -+ { "DejaVu Sans", {10, 14,} },
6429 -+ { "DejaVu Sans", {16, 17,} },
6430 -+ { "Droid Sans", {12, 12,} },
6431 -+ { "Droid Sans", {15, 15,} },
6432 -+ { "FreeMono", {0, MAX_PPEM,} },
6433 -+ { "FreeSans", {0, MAX_PPEM,} },
6434 -+ { "Liberation Mono", {0, MAX_PPEM,} },
6435 -+ { "Lucida Console", {0, MAX_PPEM,} },
6436 -+ { "Luxi Sans", {13, 13,} },
6437 -+ { "Microsoft Sans Serif", {0, MAX_PPEM,} },
6438 -+ { "Monaco", {0, MAX_PPEM,} },
6439 -+ { "Segoe UI", {11, 12,} },
6440 -+ { "Segoe UI", {14, 14,} },
6441 -+ { "Tahoma", {11, 11,} },
6442 -+ { "Tahoma", {14, MAX_PPEM,} },
6443 -+ { "Times New Roman", {14, 14,} },
6444 -+ { "Times New Roman", {16, 16,} },
6445 -+ { "Trebuchet MS", {13, 13,} },
6446 -+ { "Ubuntu", {12, 13,} },
6447 -+ { "Ubuntu", {15, 15,} },
6448 -+ { "Verdana", {0, 14,} },
6449 -+ { "Verdana", {16, MAX_PPEM,} },
6450 -+ { "Pragmata", {0, MAX_PPEM,} },
6451 -+ { "Essential PragmataPro", {0, MAX_PPEM,} },
6452 -+ };
6453 -+
6454 -+
6455 -+
6456 -+
6457 -+#define AUTOHINT_BRIGHTNESS_RULES_SIZE 3
6458 -+ SA_Rule BRIGHTNESS_Rules
6459 -+ [AUTOHINT_BRIGHTNESS_RULES_SIZE] =
6460 -+ {
6461 -+ { "Baskerville", {0, -20,} },
6462 -+ { "Garamond", {0, -20,} },
6463 -+ { "Optima", {0, -20,} },
6464 -+ };
6465 -+
6466 -+#define AUTOHINT_CONTRAST_RULES_SIZE 3
6467 -+ SA_Rule CONTRAST_Rules
6468 -+ [AUTOHINT_CONTRAST_RULES_SIZE] =
6469 -+ {
6470 -+ { "Baskerville", {0, 25,} },
6471 -+ { "Garamond", {0, 25,} },
6472 -+ { "Optima", {0, 25,} },
6473 -+ };
6474 -+
6475 -+#if 0
6476 -+#define STEM_SPACING_RULES_SIZE 3
6477 -+ SA_Rule STEM_SPACING_Rules
6478 -+ [STEM_SPACING_RULES_SIZE] =
6479 -+ {
6480 -+ { "Tahoma", {10, 12, 18, 18, 30} },
6481 -+ { "Arial", {10, 11, 23, 25, 30} },
6482 -+ { "Freesans", {10, 12, 18, 18, 30} },
6483 -+ };
6484 -+
6485 -+#define STEM_START_RULES_SIZE 3
6486 -+ SA_Rule STEM_START_Rules
6487 -+ [STEM_START_RULES_SIZE] =
6488 -+ {
6489 -+ { "Tahoma", {14, 17, 30, 100, 100} },
6490 -+ { "Arial", {11, 18, 23, 30, 30} },
6491 -+ { "Freesans", {10, 18, 18, 25, 30} },
6492 -+ };
6493 -+#endif
6494 -+
6495 -+ typedef struct Stem_Data_
6496 -+ {
6497 -+ FT_Int stem_width;
6498 -+ FT_Int stem_spacing;
6499 -+ FT_Int stem_start;
6500 -+ FT_Int stem_scaling;
6501 -+ FT_Int stem_translating_only;
6502 -+ FT_Int stem_translating;
6503 -+ FT_Int brightness;
6504 -+ FT_Int contrast;
6505 -+ FT_Bool use_100;
6506 -+ FT_Bool synth_stems;
6507 -+ FT_Bool edge_detection;
6508 -+ FT_Bool bearing_correction;
6509 -+ FT_Int m;
6510 -+ } Stem_Data;
6511 -+
6512 -+
6513 -+ typedef struct Stem_Segment_
6514 -+ {
6515 -+ FT_Long x1;
6516 -+ FT_Long x2;
6517 -+ FT_Int y;
6518 -+ } Stem_Segment;
6519 -+
6520 -+ typedef struct Stem_Center_
6521 -+ {
6522 -+ FT_Long x;
6523 -+ FT_Long y;
6524 -+ FT_Long w;
6525 -+ FT_Long x1;
6526 -+ FT_Long x2;
6527 -+ } Stem_Center;
6528 -+
6529 -+ typedef struct Stem_
6530 -+ {
6531 -+ FT_Long center;
6532 -+ FT_Long count;
6533 -+ FT_Long rcount; /* used to count within a range in possible stems */
6534 -+ FT_Long width;
6535 -+ FT_Long height;
6536 -+ FT_Short zone; /* 1 2 or 3 */
6537 -+ FT_Bool generated;
6538 -+ } Stem;
6539 -+
6540 -+
6541 -+ static void
6542 -+ swap_stem ( Stem* s1, Stem* s2 )
6543 -+ {
6544 -+ Stem s;
6545 -+ s.center = s1->center;
6546 -+ s.count = s1->count;
6547 -+ s.rcount = s1->rcount;
6548 -+ s.width = s1->width;
6549 -+ s.zone = s1->zone;
6550 -+ s.generated = s1->generated;
6551 -+
6552 -+ s1->center = s2->center;
6553 -+ s1->count = s2->count;
6554 -+ s1->rcount = s2->rcount;
6555 -+ s1->width = s2->width;
6556 -+ s1->zone = s2->zone;
6557 -+ s1->generated = s2->generated;
6558 -+
6559 -+ s2->center = s.center;
6560 -+ s2->count = s.count;
6561 -+ s2->rcount = s.rcount;
6562 -+ s2->width = s.width;
6563 -+ s2->zone = s.zone;
6564 -+ s2->generated = s.generated;
6565 -+ }
6566 -+
6567 -+
6568 -+ FT_LOCAL_DEF( void )
6569 -+ sa_fill_known_stem_values (
6570 -+ FT_String* family,
6571 -+ int ppem,
6572 -+ FT_String* style,
6573 -+ FT_UInt num_stems,
6574 -+ Stem_Data* known_stem_values )
6575 -+ {
6576 -+ FT_Int i, j;
6577 -+ if (verbose) printf("%s ", family);
6578 -+
6579 -+ i = 0;
6580 -+ while ( i < SNAPPING_STEM_WIDTHS_RULES_SIZE )
6581 -+ {
6582 -+ if ( family &&
6583 -+ ( strcasecmp( SNAPPING_STEM_WIDTHS_Rules[i].family, family ) == 0 ) )
6584 -+ {
6585 -+ j = 0;
6586 -+ known_stem_values->stem_width = 1;
6587 -+
6588 -+ while (j < 4)
6589 -+ {
6590 -+ if (SNAPPING_STEM_WIDTHS_Rules[i].ppem[j] == MAX_PPEM )
6591 -+ {
6592 -+ known_stem_values->stem_width = -1; /* use default */
6593 -+ j = 5;
6594 -+ i = SNAPPING_STEM_WIDTHS_RULES_SIZE;
6595 -+ }
6596 -+ else if (ppem < SNAPPING_STEM_WIDTHS_Rules[i].ppem[j])
6597 -+ {
6598 -+ known_stem_values->stem_width = j;
6599 -+ j = 5;
6600 -+ i = SNAPPING_STEM_WIDTHS_RULES_SIZE;
6601 -+ }
6602 -+ j++;
6603 -+ }
6604 -+ }
6605 -+ i++;
6606 -+ }
6607 -+
6608 -+ i = 0;
6609 -+ while ( i < SNAPPING_STEM_SCALING_RULES_SIZE )
6610 -+ {
6611 -+ if ( family &&
6612 -+ ( strcasecmp( SNAPPING_STEM_SCALING_Rules[i].family, family ) == 0 ) )
6613 -+ {
6614 -+ known_stem_values->stem_scaling = -1; /* default */
6615 -+
6616 -+ if (ppem == SNAPPING_STEM_SCALING_Rules[i].ppem[0])
6617 -+ {
6618 -+ known_stem_values->stem_scaling = SNAPPING_STEM_SCALING_Rules[i].ppem[1];
6619 -+ i = SNAPPING_STEM_SCALING_RULES_SIZE;
6620 -+ }
6621 -+ }
6622 -+ i++;
6623 -+ }
6624 -+
6625 -+
6626 -+ i = 0;
6627 -+ while ( i < SNAPPING_M_RULES_SIZE )
6628 -+ {
6629 -+ if ( family &&
6630 -+ ( strcasecmp( SNAPPING_M_Rules[i].family, family ) == 0 ) )
6631 -+ {
6632 -+ known_stem_values->m = -1; /* default */
6633 -+
6634 -+ if (ppem == SNAPPING_M_Rules[i].ppem[0])
6635 -+ {
6636 -+ known_stem_values->m = SNAPPING_M_Rules[i].ppem[1];
6637 -+ i = SNAPPING_M_RULES_SIZE;
6638 -+ }
6639 -+ }
6640 -+ i++;
6641 -+ }
6642 -+
6643 -+ i = 0;
6644 -+ while ( i < SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE )
6645 -+ {
6646 -+ if ( family &&
6647 -+ ( strcasecmp( SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].family, family ) == 0 ) )
6648 -+ {
6649 -+ known_stem_values->stem_translating_only = -1024; /* default */
6650 -+
6651 -+ if (ppem == SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0]
6652 -+ || SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[0] == 0)
6653 -+ {
6654 -+ known_stem_values->stem_translating_only = SNAPPING_STEM_TRANSLATING_ONLY_Rules[i].ppem[1];
6655 -+ i = SNAPPING_STEM_TRANSLATING_ONLY_RULES_SIZE;
6656 -+ }
6657 -+ }
6658 -+ i++;
6659 -+ }
6660 -+
6661 -+ i = 0;
6662 -+ while ( i < SNAPPING_STEM_TRANSLATING_RULES_SIZE )
6663 -+ {
6664 -+ if ( family &&
6665 -+ ( strcasecmp( SNAPPING_STEM_TRANSLATING_Rules[i].family, family ) == 0 ) )
6666 -+ {
6667 -+ known_stem_values->stem_translating = 0; /* default */
6668 -+
6669 -+ if (ppem == SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0]
6670 -+ || SNAPPING_STEM_TRANSLATING_Rules[i].ppem[0] == 0)
6671 -+ {
6672 -+ known_stem_values->stem_translating = SNAPPING_STEM_TRANSLATING_Rules[i].ppem[1];
6673 -+ i = SNAPPING_STEM_TRANSLATING_RULES_SIZE;
6674 -+ }
6675 -+ }
6676 -+ i++;
6677 -+ }
6678 -+
6679 -+
6680 -+ i = 0;
6681 -+ while ( i < ALWAYS_USE_100_RULES_SIZE )
6682 -+ {
6683 -+ if ( family &&
6684 -+ ( strcasecmp( ALWAYS_USE_100_Rules[i].family, family ) == 0 ) )
6685 -+ {
6686 -+ known_stem_values->use_100 = FALSE; /* default */
6687 -+
6688 -+ if (ppem >= ALWAYS_USE_100_Rules[i].ppem[0] && ppem <= ALWAYS_USE_100_Rules[i].ppem[1] )
6689 -+ {
6690 -+ known_stem_values->use_100 = TRUE;
6691 -+ i = ALWAYS_USE_100_RULES_SIZE;
6692 -+ }
6693 -+ }
6694 -+ i++;
6695 -+ }
6696 -+
6697 -+
6698 -+ i = 0;
6699 -+ while ( i < SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE )
6700 -+ {
6701 -+ if ( family &&
6702 -+ ( strcasecmp( SNAPPING_SYNTHESIZE_STEMS_Rules[i].family, family ) == 0 ) )
6703 -+ {
6704 -+ known_stem_values->synth_stems = FALSE; /* default */
6705 -+
6706 -+ if (ppem >= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[0] && ppem <= SNAPPING_SYNTHESIZE_STEMS_Rules[i].ppem[1] )
6707 -+ {
6708 -+ known_stem_values->synth_stems = TRUE;
6709 -+ i = SNAPPING_SYNTHESIZE_STEMS_RULES_SIZE;
6710 -+ }
6711 -+ }
6712 -+ i++;
6713 -+ }
6714 -+
6715 -+
6716 -+ i = 0;
6717 -+ while ( i < SNAPPING_EDGE_DETECTION_RULES_SIZE )
6718 -+ {
6719 -+ if ( family &&
6720 -+ ( strcasecmp( SNAPPING_EDGE_DETECTION_Rules[i].family, family ) == 0 ) )
6721 -+ {
6722 -+ known_stem_values->edge_detection = FALSE; /* default */
6723 -+
6724 -+ if (ppem >= SNAPPING_EDGE_DETECTION_Rules[i].ppem[0] && ppem <= SNAPPING_EDGE_DETECTION_Rules[i].ppem[1] )
6725 -+ {
6726 -+ known_stem_values->edge_detection = TRUE;
6727 -+ i = SNAPPING_EDGE_DETECTION_RULES_SIZE;
6728 -+ }
6729 -+ }
6730 -+ i++;
6731 -+ }
6732 -+
6733 -+
6734 -+ i = 0;
6735 -+ while ( i < SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE )
6736 -+ {
6737 -+ if ( family &&
6738 -+ ( strcasecmp( SNAPPING_NO_BEARING_CORRECTION_Rules[i].family, family ) == 0 ) )
6739 -+ {
6740 -+ known_stem_values->bearing_correction = TRUE; /* default */
6741 -+
6742 -+ if (ppem >= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[0] && ppem <= SNAPPING_NO_BEARING_CORRECTION_Rules[i].ppem[1] )
6743 -+ {
6744 -+ known_stem_values->bearing_correction = FALSE;
6745 -+ i = SNAPPING_NO_BEARING_CORRECTION_RULES_SIZE;
6746 -+ }
6747 -+ }
6748 -+ i++;
6749 -+ }
6750 -+
6751 -+
6752 -+#if 0
6753 -+ i = 0;
6754 -+ while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE )
6755 -+ {
6756 -+ if ( family &&
6757 -+ ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) )
6758 -+ {
6759 -+ known_stem_values->brightness = 0.0;
6760 -+
6761 -+ if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0)
6762 -+ {
6763 -+ known_stem_values->brightness = BRIGHTNESS_Rules[i].ppem[1];
6764 -+ i = AUTOHINT_BRIGHTNESS_RULES_SIZE;
6765 -+ }
6766 -+ }
6767 -+ i++;
6768 -+ }
6769 -+
6770 -+ i = 0;
6771 -+ while ( i < AUTOHINT_CONTRAST_RULES_SIZE )
6772 -+ {
6773 -+ if ( family &&
6774 -+ ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) )
6775 -+ {
6776 -+ known_stem_values->contrast = 0.0;
6777 -+
6778 -+ if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0)
6779 -+ {
6780 -+ known_stem_values->contrast = CONTRAST_Rules[i].ppem[1];
6781 -+ i = AUTOHINT_CONTRAST_RULES_SIZE;
6782 -+ }
6783 -+ }
6784 -+ i++;
6785 -+ }
6786 -+
6787 -+ for ( i = 0; i <= STEM_SPACING_RULES_SIZE; i++ )
6788 -+ {
6789 -+ if ( family &&
6790 -+ ( strcasecmp( STEM_SPACING_Rules[i].family, family ) == 0 ) )
6791 -+ {
6792 -+ j = 0;
6793 -+ known_stem_values->stem_spacing = 2; /* default */
6794 -+
6795 -+ while (j < 4)
6796 -+ {
6797 -+ if (ppem < STEM_SPACING_Rules[i].ppem[j])
6798 -+ {
6799 -+ known_stem_values->stem_spacing = j;
6800 -+ j = 5;
6801 -+ }
6802 -+ j++;
6803 -+ }
6804 -+ }
6805 -+ }
6806 -+
6807 -+
6808 -+ for ( i = 0; i <= STEM_START_RULES_SIZE; i++ )
6809 -+ {
6810 -+ if ( family &&
6811 -+ ( strcasecmp( STEM_START_Rules[i].family, family ) == 0 ) )
6812 -+ {
6813 -+ j = 0;
6814 -+ known_stem_values->stem_start = 1; /* default */
6815 -+
6816 -+ while (j < 4)
6817 -+ {
6818 -+ if (ppem < STEM_START_Rules[i].ppem[j])
6819 -+ {
6820 -+ known_stem_values->stem_start = j;
6821 -+ j = 5;
6822 -+ }
6823 -+ j++;
6824 -+ }
6825 -+ }
6826 -+ }
6827 -+#endif
6828 -+ }
6829 -+
6830 -+
6831 -+ FT_LOCAL_DEF( FT_Int )
6832 -+ get_contrast (
6833 -+ FT_String* family,
6834 -+ int ppem)
6835 -+ {
6836 -+ FT_Int i;
6837 -+ if (verbose) printf("%s ", family);
6838 -+
6839 -+ i = 0;
6840 -+ while ( i < AUTOHINT_CONTRAST_RULES_SIZE )
6841 -+ {
6842 -+ if ( family &&
6843 -+ ( strcasecmp( CONTRAST_Rules[i].family, family ) == 0 ) )
6844 -+ {
6845 -+ if (ppem == CONTRAST_Rules[i].ppem[0] || CONTRAST_Rules[i].ppem[0] == 0)
6846 -+ {
6847 -+ return CONTRAST_Rules[i].ppem[1];
6848 -+ }
6849 -+ }
6850 -+ i++;
6851 -+ }
6852 -+ return 0;
6853 -+ }
6854 -+
6855 -+
6856 -+ FT_LOCAL_DEF( FT_Int )
6857 -+ get_brightness (
6858 -+ FT_String* family,
6859 -+ int ppem)
6860 -+ {
6861 -+ FT_Int i;
6862 -+ if (verbose) printf("%s ", family);
6863 -+
6864 -+ i = 0;
6865 -+ while ( i < AUTOHINT_BRIGHTNESS_RULES_SIZE )
6866 -+ {
6867 -+ if ( family &&
6868 -+ ( strcasecmp( BRIGHTNESS_Rules[i].family, family ) == 0 ) )
6869 -+ {
6870 -+ if (ppem == BRIGHTNESS_Rules[i].ppem[0] || BRIGHTNESS_Rules[i].ppem[0] == 0)
6871 -+ {
6872 -+ return BRIGHTNESS_Rules[i].ppem[1];
6873 -+ }
6874 -+ }
6875 -+ i++;
6876 -+ }
6877 -+ return 0;
6878 -+ }
6879 -+
6880 -+
6881 -+ /* Stem alignment for bitmaps; A hack with very nice results */
6882 -+ /* Ideally this could be implemented on the outline, prior to
6883 -+ * rasterization. Possible future enhancement is to use the
6884 -+ * warper code to achieve this */
6885 -+ static void
6886 -+ _lcd_stem_align ( FT_Bitmap* bitmap,
6887 -+ FT_Render_Mode mode,
6888 -+ FT_GlyphSlot slot,
6889 -+ FT_Long* translate_value,
6890 -+ float* scale_value,
6891 -+ FT_UInt alignment_strength,
6892 -+ FT_UInt fitting_strength,
6893 -+ float* embolden_value
6894 -+ )
6895 -+ {
6896 -+ FT_UInt width = (FT_UInt)bitmap->width;
6897 -+ FT_UInt height = (FT_UInt)bitmap->rows;
6898 -+
6899 -+ Stem_Segment* segments;
6900 -+ Stem_Segment* leftmost_segment;
6901 -+ Stem_Segment* rightmost_segment;
6902 -+ Stem_Segment* leftmost_segment_not_extrema;
6903 -+ Stem_Segment* rightmost_segment_not_extrema;
6904 -+ Stem* stems;
6905 -+ Stem* possible_stems;
6906 -+ Stem* leftmost_stem;
6907 -+ Stem* rightmost_stem;
6908 -+ Stem_Data* known_stem_values;
6909 -+ Stem_Center* centers;
6910 -+ FT_Long leftmost_point = width * 256;
6911 -+ FT_Long rightmost_point = 0;
6912 -+ FT_Long leftmost_point_not_extrema = width * 256;
6913 -+ FT_Long rightmost_point_not_extrema = 0;
6914 -+ FT_Long num_segments = 0;
6915 -+ FT_Long num_centers = 0;
6916 -+ FT_Long stem_centers[width * 256];
6917 -+ FT_UInt h;
6918 -+ FT_ULong valid_stems = 0, valid_possible_stems = 0;
6919 -+ FT_Long center, stem_matches, stem_matches_ledge;
6920 -+ FT_Long stem_matches_redge, next_center, last_matching_center;
6921 -+ FT_Long last_matching_ledge, last_matching_redge, this_center;
6922 -+ FT_Int max_strength;
6923 -+ FT_Byte* line = bitmap->buffer;
6924 -+ FT_UInt current_value = 0;
6925 -+ FT_UInt xx;
6926 -+ FT_Long linearHoriAdvance = slot->linearHoriAdvance >> 10;
6927 -+
6928 -+ FT_Int m_horiBearingX = slot->metrics.horiBearingX;
6929 -+ FT_Int m_horiAdvance = slot->metrics.horiAdvance;
6930 -+ FT_Int m_width = slot->metrics.width;
6931 -+ FT_Pos one_pixel = 768;
6932 -+ FT_Pos one_third_pixel = 256;
6933 -+ FT_Int columns_per_pixel = 3;
6934 -+ /*FT_Int extra_columns = 6;*/
6935 -+
6936 -+ /* on / off flags for testing different features */
6937 -+ FT_Bool strategy_translate_using_closest_stem = TRUE;
6938 -+ FT_Bool strategy_scale_to_closest_centers = FALSE;
6939 -+ FT_Bool strategy_scale_to_closest_centers_up_only = FALSE;
6940 -+ FT_Bool strategy_always_use_distance_ceiling = FALSE;
6941 -+ FT_Bool strategy_auto_change_center_offset = TRUE;
6942 -+ FT_Bool strategy_use_m_control = FALSE;
6943 -+ FT_Bool strategy_correct_out_of_bounds_outlines = FALSE; /*this needs work.. breaks some glyphs like verdana 12 */
6944 -+ FT_Bool strategy_also_use_edge_detection_for_stems = FALSE;
6945 -+ FT_Bool strategy_use_strengths = TRUE;
6946 -+ FT_Bool strategy_synthesize_stems = FALSE;
6947 -+ FT_Bool strategy_bearing_correction = TRUE;
6948 -+ FT_Bool strategy_use_d_correction = TRUE;
6949 -+ FT_Bool strategy_fit_to_width = FALSE;
6950 -+ /*FT_Bool strategy_center_glyph = FALSE;*/
6951 -+ FT_Bool strategy_use_verdana_12_hack = FALSE; /* not necessary anymore... maybe */
6952 -+ FT_Bool has_serifs = FALSE;
6953 -+ FT_Bool autohinted = FALSE;
6954 -+
6955 -+ const FT_Int MIN_PPEM = 7;
6956 -+ /*const FT_Int MAX_PPEM = 100;*/
6957 -+ const FT_Int MAX_STEMS = 3;
6958 -+ FT_Int ppem = 0;
6959 -+
6960 -+ int checked_use_known_settings_on_selected_fonts_env = 0;
6961 -+ FT_Bool use_known_settings_on_selected_fonts = FALSE;
6962 -+
6963 -+ int cur_width;
6964 -+ char *cur_width_env = getenv( "CUR_WIDTH" );
6965 -+
6966 -+ if ( cur_width_env != NULL ){
6967 -+ sscanf ( cur_width_env, "%d", &cur_width );
6968 -+ if (cur_width != 0) autohinted = TRUE;
6969 -+ }
6970 -+
6971 -+ /* An incoming scale value of 1.1 indicates to do certain things */
6972 -+ /*if (*scale_value == 1.1) strategy_use_verdana_12_hack = TRUE;*/
6973 -+
6974 -+ /* reset to default */
6975 -+ *scale_value = 1.0;
6976 -+
6977 -+ if ( checked_use_known_settings_on_selected_fonts_env == 0 )
6978 -+ {
6979 -+ char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" );
6980 -+ if ( use_known_settings_on_selected_fonts_env != NULL )
6981 -+ {
6982 -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 )
6983 -+ {
6984 -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0)
6985 -+ use_known_settings_on_selected_fonts = TRUE;
6986 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0)
6987 -+ use_known_settings_on_selected_fonts = TRUE;
6988 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0)
6989 -+ use_known_settings_on_selected_fonts = TRUE;
6990 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0)
6991 -+ use_known_settings_on_selected_fonts = TRUE;
6992 -+ }
6993 -+ }
6994 -+ checked_use_known_settings_on_selected_fonts_env = 1;
6995 -+ }
6996 -+
6997 -+
6998 -+ /* Simply return in odd cases where these don't seem to be set */
6999 -+ /* Flash and some pdf viewers will crash otherwise */
7000 -+ if ( !slot->face || !slot->face->size || !slot->face->size->metrics.x_ppem )
7001 -+ return;
7002 -+ if ( slot->face->size->metrics.x_ppem > MAX_PPEM ) return;
7003 -+ /*if ( width < 4 ) return;*/
7004 -+
7005 -+ if ( slot->face->size->metrics.x_ppem < MIN_PPEM ) return;
7006 -+
7007 -+ if ( !FT_IS_SCALABLE( slot->face ) ) return;
7008 -+
7009 -+ ppem = slot->face->size->metrics.x_ppem;
7010 -+
7011 -+
7012 -+ /* only perform alignment on styles we know, that aren't bold or italic */
7013 -+ /* perhaps detection could be added on those that are not set? */
7014 -+ /* Require certain ppems for narrow and light fonts */
7015 -+ if( slot->face->style_name )
7016 -+ {
7017 -+ if ( strcasestr(slot->face->style_name, "Italic")
7018 -+ || strcasestr(slot->face->style_name, "Oblique")
7019 -+ || strcasestr(slot->face->style_name, "Script")
7020 -+ || strcasestr(slot->face->style_name, "Handwriting")
7021 -+ || strcasestr(slot->face->style_name, "Bold")
7022 -+ || strcasestr(slot->face->style_name, "Black")
7023 -+ || ( ( strcasestr(slot->face->style_name, "Extra Thin")
7024 -+ || strcasestr(slot->face->style_name, "Extra Light") )
7025 -+ && ppem < 10 )
7026 -+ || ( strcasestr(slot->face->style_name, "Thin")
7027 -+ && ppem < 10 )
7028 -+ || ( strcasestr(slot->face->style_name, "Light")
7029 -+ && ppem < 10 )
7030 -+ || ( strcasestr(slot->face->style_name, "Narrow")
7031 -+ && ppem < 15 )
7032 -+ || ( strcasestr(slot->face->style_name, "Condensed")
7033 -+ && ppem < 20 ) )
7034 -+ return;
7035 -+ }
7036 -+
7037 -+ if( slot->face->family_name )
7038 -+ {
7039 -+ if ( strcasestr(slot->face->family_name, "Italic")
7040 -+ || strcasestr(slot->face->family_name, "Oblique")
7041 -+ || strcasestr(slot->face->family_name, "Script")
7042 -+ || strcasestr(slot->face->family_name, "Handwriting")
7043 -+ || strcasestr(slot->face->family_name, "Bold")
7044 -+ || strcasestr(slot->face->family_name, "Black")
7045 -+ || ( ( strcasestr(slot->face->family_name, "Extra Thin")
7046 -+ || strcasestr(slot->face->family_name, "Extra Light") )
7047 -+ && ppem < 10 )
7048 -+ || ( strcasestr(slot->face->family_name, "Thin")
7049 -+ && ppem < 10 )
7050 -+ || ( strcasestr(slot->face->family_name, "Light")
7051 -+ && ppem < 10 )
7052 -+ || ( strcasestr(slot->face->family_name, "Narrow")
7053 -+ && ppem < 15 )
7054 -+ || ( strcasestr(slot->face->family_name, "Condensed")
7055 -+ && ppem < 20 ) )
7056 -+ return;
7057 -+ }
7058 -+ else if ( slot->face->style_flags )
7059 -+ {
7060 -+ if ( slot->face->style_flags & FT_STYLE_FLAG_ITALIC
7061 -+ || slot->face->style_flags & FT_STYLE_FLAG_BOLD
7062 -+ || FT_IS_TRICKY( slot->face ) )
7063 -+ return;
7064 -+ }
7065 -+ else return;
7066 -+
7067 -+ if( slot->face->family_name )
7068 -+ {
7069 -+ if ( strcasestr(slot->face->family_name, "Courier")
7070 -+ || strcasestr(slot->face->family_name, "Serif")
7071 -+ || strcasestr(slot->face->family_name, "Times"))
7072 -+ has_serifs = TRUE;
7073 -+ }
7074 -+
7075 -+ if ( mode != FT_RENDER_MODE_LCD )
7076 -+ {
7077 -+ columns_per_pixel = 1;
7078 -+ one_pixel = 256;
7079 -+ one_third_pixel = 85;
7080 -+ /*extra_columns = 0;*/
7081 -+ /* until this can be figured out just return */
7082 -+ /* There are issues with missing glyphs */
7083 -+ return;
7084 -+ }
7085 -+
7086 -+ known_stem_values = (Stem_Data*) malloc (columns_per_pixel * sizeof(Stem_Data)); /* only look at top 3 for now */
7087 -+ known_stem_values->stem_spacing = -1;
7088 -+ known_stem_values->stem_width = -1;
7089 -+ known_stem_values->stem_start = -1;
7090 -+ known_stem_values->stem_scaling = -1;
7091 -+ known_stem_values->stem_translating_only = -1024;
7092 -+ known_stem_values->stem_translating = 0;
7093 -+ known_stem_values->brightness = 0;
7094 -+ known_stem_values->contrast = 0;
7095 -+ known_stem_values->use_100 = FALSE;
7096 -+ known_stem_values->m = -1;
7097 -+ known_stem_values->synth_stems = FALSE;
7098 -+ known_stem_values->bearing_correction = TRUE;
7099 -+
7100 -+ if (use_known_settings_on_selected_fonts)
7101 -+ {
7102 -+ sa_fill_known_stem_values ( slot->face->family_name,
7103 -+ ppem, slot->face->style_name,
7104 -+ valid_stems, known_stem_values );
7105 -+ if (verbose)
7106 -+ printf ("width:%d,spacing:%d,start:%d,scaling:%d,translate:%d ",
7107 -+ known_stem_values->stem_width, known_stem_values->stem_spacing,
7108 -+ known_stem_values->stem_start, known_stem_values->stem_scaling,
7109 -+ known_stem_values->stem_translating_only) ;
7110 -+ }
7111 -+
7112 -+ /* translate value may be set for < 10 */
7113 -+ if (use_known_settings_on_selected_fonts && known_stem_values->stem_translating_only > -1024 )
7114 -+ {
7115 -+ *translate_value = known_stem_values->stem_translating_only;
7116 -+ return;
7117 -+ }
7118 -+
7119 -+ if (use_known_settings_on_selected_fonts && known_stem_values->bearing_correction == FALSE )
7120 -+ {
7121 -+ strategy_bearing_correction = FALSE;
7122 -+ }
7123 -+
7124 -+ if ( known_stem_values->use_100 || known_stem_values->m >= 0)
7125 -+ {
7126 -+ alignment_strength = fitting_strength = 100;
7127 -+ strategy_use_m_control = TRUE;
7128 -+ }
7129 -+
7130 -+ if ( known_stem_values->edge_detection )
7131 -+ {
7132 -+ strategy_also_use_edge_detection_for_stems = TRUE;
7133 -+ }
7134 -+
7135 -+ if ( ppem < 9 ) return;
7136 -+ if ( ppem > 20 ) strategy_use_m_control = TRUE;
7137 -+
7138 -+ /* Allocate */
7139 -+ segments = (Stem_Segment*) malloc( (1) * sizeof (Stem_Segment));
7140 -+ leftmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment));
7141 -+ leftmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment));
7142 -+ rightmost_segment = (Stem_Segment*) malloc( sizeof (Stem_Segment));
7143 -+ rightmost_segment_not_extrema = (Stem_Segment*) malloc( sizeof (Stem_Segment));
7144 -+
7145 -+ stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem));
7146 -+ possible_stems = (Stem*) malloc (MAX_STEMS * sizeof(Stem));
7147 -+ leftmost_stem = (Stem*) malloc ( sizeof(Stem));
7148 -+ rightmost_stem = (Stem*) malloc ( sizeof(Stem));
7149 -+ centers = (Stem_Center*) malloc ( (1) * sizeof(Stem_Center));
7150 -+
7151 -+ if (verbose) printf("\n");
7152 -+
7153 -+ /* Initialize */
7154 -+ for ( xx = 0; xx < width * 256; xx += 1 )
7155 -+ {
7156 -+ stem_centers[xx] = 0;
7157 -+ }
7158 -+ for ( xx = 0; xx < num_segments; xx += 1 )
7159 -+ {
7160 -+ segments[xx].x1 = 0;
7161 -+ segments[xx].x2 = 0;
7162 -+ segments[xx].y = 0;
7163 -+ }
7164 -+ rightmost_segment->x1 = 0;
7165 -+ rightmost_segment->x2 = 0;
7166 -+ rightmost_segment->y = 0;
7167 -+ leftmost_segment->x1 = 99999999;
7168 -+ leftmost_segment->x2 = 0;
7169 -+ leftmost_segment->y = 0;
7170 -+
7171 -+ rightmost_segment_not_extrema->x1 = 0;
7172 -+ rightmost_segment_not_extrema->x2 = 0;
7173 -+ rightmost_segment_not_extrema->y = 0;
7174 -+ leftmost_segment_not_extrema->x1 = 99999999;
7175 -+ leftmost_segment_not_extrema->x2 = 0;
7176 -+ leftmost_segment_not_extrema->y = 0;
7177 -+
7178 -+ /* Locate stem centers for later processing */
7179 -+ for ( h = (FT_UInt)bitmap->rows; h > 0; h--, line += bitmap->pitch )
7180 -+ {
7181 -+ current_value = 0;
7182 -+ /* Calculate various sums and stem widths of glyph */
7183 -+ for ( xx = 0; xx < width; xx += 1 )
7184 -+ {
7185 -+ /* Reallocate */
7186 -+ segments = (Stem_Segment*) realloc( segments, (num_segments + 1) * sizeof (Stem_Segment));
7187 -+
7188 -+ /* if line is white, and now has color, it's the start of a stem */
7189 -+ if (current_value == 0 && line[xx] > 0)
7190 -+ {
7191 -+ /* start of stem */
7192 -+ segments[num_segments].x1 = 256 * (xx) + (255 - line[xx]);
7193 -+ segments[num_segments].y = h;
7194 -+ }
7195 -+
7196 -+ /* otherwise, if it's currently black and the new value is 0, it's the end of a stem */
7197 -+ else if ( ( current_value > 0 && line[xx] == 0 )
7198 -+ || ( current_value > 0 && xx == width - 1 ) )
7199 -+ {
7200 -+ FT_Long stem_center_x/*, stem_width*/;
7201 -+ segments[num_segments].x2 = 256 * (xx-1) + line[xx-1];
7202 -+
7203 -+ if (xx == width - 1) segments[num_segments].x2 += line[xx];
7204 -+
7205 -+ /*stem center is average of start and end of stem */
7206 -+ stem_center_x = (segments[num_segments].x2 + segments[num_segments].x1) / 2;
7207 -+ /*stem_width = segments[num_segments].x2 - segments[num_segments].x1;*/
7208 -+ /* Reallocate */
7209 -+ centers = (Stem_Center*) realloc ( centers, (num_centers + 1) * sizeof(Stem_Center));
7210 -+ centers[num_centers].x = stem_center_x;
7211 -+ centers[num_centers].y = h;
7212 -+ centers[num_centers].x1 = segments[num_segments].x1;
7213 -+ centers[num_centers].x2 = segments[num_segments].x2;
7214 -+
7215 -+ num_centers++;
7216 -+
7217 -+ stem_centers[stem_center_x] += 1;
7218 -+
7219 -+ /* Find left and rightmost points for later calculations */
7220 -+ /* OR - Favor ones that aren't on the top or bottom if possible to prevent v and w from getting caught later */
7221 -+ if ( segments[num_segments].x1 < leftmost_segment->x1
7222 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height
7223 -+ && segments[num_segments].x1 == leftmost_segment->x1 ) )
7224 -+ {
7225 -+ leftmost_segment->x1 = segments[num_segments].x1;
7226 -+ leftmost_segment->x2 = segments[num_segments].x2;
7227 -+ leftmost_segment->y = h;
7228 -+ }
7229 -+ if (segments[num_segments].x2 > rightmost_segment->x2
7230 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height
7231 -+ && segments[num_segments].x1 == rightmost_segment->x1 ) )
7232 -+ {
7233 -+ rightmost_segment->x1 = segments[num_segments].x1;
7234 -+ rightmost_segment->x2 = segments[num_segments].x2;
7235 -+ rightmost_segment->y = h;
7236 -+ }
7237 -+
7238 -+ if (segments[num_segments].x1 < leftmost_segment_not_extrema->x1
7239 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height
7240 -+ && segments[num_segments].x1 == leftmost_segment_not_extrema->x1
7241 -+ && h < (FT_UInt)bitmap->rows && h > 0 ) )
7242 -+ {
7243 -+ leftmost_segment_not_extrema->x1 = segments[num_segments].x1;
7244 -+ leftmost_segment_not_extrema->x2 = segments[num_segments].x2;
7245 -+ leftmost_segment_not_extrema->y = h;
7246 -+ }
7247 -+ if (segments[num_segments].x2 > rightmost_segment_not_extrema->x2
7248 -+ || ( segments[num_segments].y > 1 && segments[num_segments].y < height
7249 -+ && segments[num_segments].x1 == rightmost_segment_not_extrema->x1
7250 -+ && h < (FT_UInt)bitmap->rows && h > 0 ) )
7251 -+ {
7252 -+ rightmost_segment_not_extrema->x1 = segments[num_segments].x1;
7253 -+ rightmost_segment_not_extrema->x2 = segments[num_segments].x2;
7254 -+ rightmost_segment_not_extrema->y = h;
7255 -+ }
7256 -+
7257 -+ if (segments[num_segments].x1 < leftmost_point)
7258 -+ {
7259 -+ leftmost_point = segments[num_segments].x1;
7260 -+ }
7261 -+ if (segments[num_segments].x2 > rightmost_point)
7262 -+ {
7263 -+ rightmost_point = segments[num_segments].x2;
7264 -+ }
7265 -+
7266 -+ if (segments[num_segments].x1 < leftmost_point_not_extrema
7267 -+ && h < (FT_UInt)bitmap->rows && h > 0)
7268 -+ {
7269 -+ leftmost_point_not_extrema = segments[num_segments].x1;
7270 -+ }
7271 -+ if (segments[num_segments].x2 > rightmost_point_not_extrema
7272 -+ && h < (FT_UInt)bitmap->rows && h > 0)
7273 -+ {
7274 -+ rightmost_point_not_extrema = segments[num_segments].x2;
7275 -+ }
7276 -+
7277 -+ num_segments++;
7278 -+ }
7279 -+ /* else - other conditions - need some error checking here */
7280 -+
7281 -+ current_value = line[xx];
7282 -+ }
7283 -+ }
7284 -+
7285 -+ /* initialize */
7286 -+ for ( xx = 0; xx < MAX_STEMS; xx +=1 )
7287 -+ {
7288 -+ stems[xx].center = 0;
7289 -+ stems[xx].count = 0;
7290 -+ stems[xx].width = 0;
7291 -+ stems[xx].height = 0;
7292 -+ possible_stems[xx].center = 0;
7293 -+ possible_stems[xx].count = 0;
7294 -+ possible_stems[xx].width = 0;
7295 -+ possible_stems[xx].height = 0;
7296 -+ }
7297 -+ valid_stems = 0;
7298 -+ valid_possible_stems = 0;
7299 -+
7300 -+ /* Determine which centers belong to stems */
7301 -+ center = 0;
7302 -+
7303 -+ while ( center < num_centers )
7304 -+ {
7305 -+ /* slope at within which to consider a point part of a stem */
7306 -+ /*const FT_UInt slope = 1;
7307 -+ const FT_UInt topslope = (256 * 3) / 10; */
7308 -+ FT_Int deviation1 = 5; /* 10 to 20 wiith 4 matches seems good, but 1 or 2 with 3 stems needs to somehow get included */
7309 -+ FT_Int deviation2=-1, requirement1 = 4, stem_match_requirement = 3;
7310 -+ FT_Int best_height = 0, center_difference_in_height;
7311 -+ FT_Int center_difference_in_width, valid_center_average;
7312 -+ FT_Int smallest_width_ledge, smallest_width_redge;
7313 -+ FT_Int x1_difference_in_width, x2_difference_in_width;
7314 -+ FT_Bool large_gap_found = FALSE, no_gap_found = FALSE;
7315 -+ FT_Bool large_gap_found_ledge = FALSE, no_gap_found_ledge = FALSE;
7316 -+ FT_Bool large_gap_found_redge = FALSE, no_gap_found_redge = FALSE;
7317 -+ FT_Bool stem_detected = FALSE;
7318 -+ FT_Int set_width_to, set_center_to;
7319 -+
7320 -+ /* seems to not do damage */
7321 -+ /* May not be effective */
7322 -+ requirement1 = height / 4;
7323 -+ if (requirement1 < 5) requirement1 = 5;
7324 -+ deviation1 = 20;
7325 -+ deviation2 = 20;
7326 -+
7327 -+ if (columns_per_pixel == 1)
7328 -+ {
7329 -+ deviation1 = deviation2 = 10;
7330 -+ }
7331 -+
7332 -+ if ((FT_Int)bitmap->rows <= 6) deviation1 = 25;
7333 -+ if ((FT_Int)bitmap->rows <= 6) deviation2 = 25;
7334 -+
7335 -+ if (columns_per_pixel == 1 && (FT_Int)bitmap->rows <= 6)
7336 -+ {
7337 -+ deviation1 = deviation2 = 12;
7338 -+ }
7339 -+
7340 -+ /* THIS WORKS, BUT NEED TO PUNISH DIAGONALS like W */
7341 -+ /*requirement2 = height / 5;
7342 -+ if (requirement2 < 3) requirement2 = 3;
7343 -+ deviation2 = 1 ;*/
7344 -+ valid_center_average = 0;
7345 -+ /* if (deviation2 < 1) deviation2 = 1;*/
7346 -+
7347 -+ large_gap_found = large_gap_found_ledge = large_gap_found_redge = FALSE;
7348 -+ no_gap_found = no_gap_found_ledge = no_gap_found_redge = FALSE;
7349 -+ stem_detected = FALSE;
7350 -+
7351 -+ if (ppem < 11)
7352 -+ {
7353 -+ requirement1 = 4;
7354 -+ }
7355 -+ if (ppem > 18 )
7356 -+ {
7357 -+ stem_match_requirement = height / 4;
7358 -+ if (stem_match_requirement < 3) stem_match_requirement = 3;
7359 -+ }
7360 -+
7361 -+ smallest_width_ledge = smallest_width_redge = width * 256;
7362 -+ stem_matches = 0;
7363 -+ stem_matches_ledge = 0;
7364 -+ stem_matches_redge = 0;
7365 -+ last_matching_center = -1;
7366 -+ last_matching_ledge = -1;
7367 -+ last_matching_redge = -1;
7368 -+
7369 -+ /* set currently looked at center to center value */
7370 -+ this_center = center;
7371 -+ next_center = 0;
7372 -+
7373 -+ /* For each center, compare with all other centers to see if others match the properties of this one */
7374 -+ while ( next_center < num_centers )
7375 -+ {
7376 -+
7377 -+ /* calculate differences */
7378 -+ center_difference_in_width = abs (centers[this_center].x - centers[next_center].x);
7379 -+ center_difference_in_height = abs (centers[this_center].y - centers[next_center].y);
7380 -+ x1_difference_in_width = abs (centers[this_center].x1 - centers[next_center].x1);
7381 -+ x2_difference_in_width = abs (centers[this_center].x2 - centers[next_center].x2);
7382 -+
7383 -+
7384 -+ /* property - stem center points that align */
7385 -+ /* 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 */
7386 -+ if ( center_difference_in_width < center_difference_in_height * deviation1
7387 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2
7388 -+ /* prevents w from getting caught ---- but also kills m */
7389 -+ && (x1_difference_in_width < center_difference_in_height * deviation2
7390 -+ || x2_difference_in_width < center_difference_in_height * deviation2 )
7391 -+
7392 -+ )
7393 -+ {
7394 -+ stem_matches += 1;
7395 -+ valid_center_average += centers[next_center].x;
7396 -+ /* try to find where the matching centers are far apart */
7397 -+ if (last_matching_center >= 0
7398 -+ && abs(centers[last_matching_center].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2)
7399 -+ large_gap_found = TRUE;
7400 -+ /* try to find where matching centers are next to each other */
7401 -+ if (last_matching_center >= 0
7402 -+ && abs(centers[last_matching_center].y - centers[next_center].y) == 1)
7403 -+ no_gap_found = TRUE;
7404 -+ last_matching_center = next_center;
7405 -+ }
7406 -+
7407 -+ if (strategy_also_use_edge_detection_for_stems){
7408 -+ /* property - stem left edge points that align */
7409 -+ /* if the center is within range, the center is less than 1/2 the height away */
7410 -+ if ( x1_difference_in_width < center_difference_in_height * deviation1
7411 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2 )
7412 -+ {
7413 -+ stem_matches_ledge += 1;
7414 -+ /* may not need for edges */
7415 -+ /*valid_center_average += centers[next_center].x; */
7416 -+
7417 -+ if (centers[next_center].x2 - centers[next_center].x1 < smallest_width_ledge )
7418 -+ smallest_width_ledge = centers[next_center].x2 - centers[next_center].x1;
7419 -+
7420 -+ /* try to find where the matching centers are far apart */
7421 -+ if (last_matching_ledge >= 0
7422 -+ && abs(centers[last_matching_ledge].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2)
7423 -+ large_gap_found_ledge = TRUE;
7424 -+ /* try to find where matching centers are next to each other */
7425 -+ if (last_matching_ledge >= 0
7426 -+ && abs(centers[last_matching_ledge].y - centers[next_center].y) == 1)
7427 -+ no_gap_found_ledge = TRUE;
7428 -+ last_matching_ledge = next_center;
7429 -+ }
7430 -+ }
7431 -+
7432 -+ if (strategy_also_use_edge_detection_for_stems){
7433 -+ /* property - stem right edge points that align */
7434 -+ /* if the center is within range, the center is less than 1/2 the height away */
7435 -+ if ( x2_difference_in_width < center_difference_in_height * deviation1
7436 -+ && center_difference_in_height <= (FT_Int)bitmap->rows / 2 )
7437 -+ {
7438 -+ stem_matches_redge += 1;
7439 -+ /* may not need for edges */
7440 -+ /*valid_center_average += centers[next_center].x; */
7441 -+
7442 -+ if (centers[next_center].x2 - centers[next_center].x1 < smallest_width_redge )
7443 -+ smallest_width_redge = centers[next_center].x2 - centers[next_center].x1;
7444 -+
7445 -+ /* try to find where the matching centers are far apart */
7446 -+ if (last_matching_redge >= 0
7447 -+ && abs(centers[last_matching_redge].y - centers[next_center].y) >= (FT_Int)bitmap->rows / 2)
7448 -+ large_gap_found_redge = TRUE;
7449 -+ /* try to find where matching centers are next to each other */
7450 -+ if (last_matching_redge >= 0
7451 -+ && abs(centers[last_matching_redge].y - centers[next_center].y) == 1)
7452 -+ no_gap_found_redge = TRUE;
7453 -+ last_matching_redge = next_center;
7454 -+ }
7455 -+ }
7456 -+
7457 -+ next_center++;
7458 -+ }
7459 -+
7460 -+ if (stem_matches > 0 ) valid_center_average /= stem_matches;
7461 -+
7462 -+ best_height = stem_matches;
7463 -+
7464 -+ /* new version */
7465 -+ if ( ( stem_matches >= stem_match_requirement
7466 -+ || ( ( (FT_Int)bitmap->rows <= 6 || ppem < 11)
7467 -+ && stem_matches >= 2
7468 -+ && abs(valid_center_average - centers[center].x) < deviation1 /2 )
7469 -+ /* try to catch tightly aligned stuff where the matching centers are next to each other only */
7470 -+ || ( stem_matches == 2
7471 -+ && abs(valid_center_average - centers[center].x) <= deviation1 /2
7472 -+ && no_gap_found && ppem < 18 ) /* catches things like times 16 u but gets a lot of w's too */
7473 -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */
7474 -+ )
7475 -+ &&
7476 -+ ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2
7477 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel ) )
7478 -+ {
7479 -+ stem_detected = TRUE;
7480 -+ set_width_to = centers[center].x2 - centers[center].x1;
7481 -+ best_height = stem_matches;
7482 -+ set_center_to = centers[center].x;
7483 -+
7484 -+ }
7485 -+ /* see if edges found anything */
7486 -+ if (strategy_also_use_edge_detection_for_stems && !stem_detected)
7487 -+ {
7488 -+ if ((
7489 -+ /* Require no gap for edges */
7490 -+ stem_matches_ledge >= stem_match_requirement && no_gap_found_ledge
7491 -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */
7492 -+ ) && ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2
7493 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel)
7494 -+ /* The stem occurs on the left side of glyph only */
7495 -+ && centers[center].x < (m_horiAdvance * 12) / 2
7496 -+
7497 -+ )
7498 -+ {
7499 -+ stem_detected = TRUE;
7500 -+ set_width_to = smallest_width_ledge;
7501 -+ best_height = stem_matches_ledge;
7502 -+ set_center_to = centers[center].x1 + set_width_to / 2;
7503 -+ stem_matches = stem_matches_ledge;
7504 -+ }
7505 -+ else if ((
7506 -+ /* Require no gap for edges */
7507 -+ stem_matches_redge >= stem_match_requirement && no_gap_found_redge
7508 -+ /* stem width is less than 1/3 of the bitmap width, or bitmap_width is small */
7509 -+ ) && ( centers[center].x2 - centers[center].x1 < (m_horiAdvance * 12) / 2
7510 -+ || m_horiAdvance * 12 <= columns_per_pixel * one_pixel)
7511 -+ /* The stem occurs on the right side of glyph only */
7512 -+ && centers[center].x > (m_horiAdvance * 12) / 2
7513 -+ )
7514 -+ {
7515 -+ stem_detected = TRUE;
7516 -+ set_width_to = smallest_width_redge;
7517 -+ best_height = stem_matches_redge;
7518 -+ set_center_to = centers[center].x2 - set_width_to / 2;
7519 -+ stem_matches = stem_matches_redge;
7520 -+ }
7521 -+ }
7522 -+
7523 -+
7524 -+ /*store and/or replace highest occurrences with 3 or more centers */
7525 -+ /* because this matched, it will become the top dog regardless */
7526 -+ if ( stem_detected )
7527 -+ if ( stem_matches > possible_stems[0].height )
7528 -+ {
7529 -+ /* if this is the first stem just go ahead */
7530 -+ if (valid_possible_stems == 0)
7531 -+ {
7532 -+ valid_possible_stems = 1;
7533 -+ possible_stems[0].center = set_center_to;
7534 -+ possible_stems[0].count = stem_matches;
7535 -+ possible_stems[0].width = set_width_to;
7536 -+ possible_stems[0].height = stem_matches;
7537 -+ }
7538 -+
7539 -+ /* otherwise, if there is already a stem */
7540 -+ else if (valid_possible_stems == 1 )
7541 -+ {
7542 -+ /* if the stem is within the range of existing one, replace existing one */
7543 -+
7544 -+ /* if the stem isn't within the range of this one swap it with next one first */
7545 -+ if (abs(set_center_to - possible_stems[0].center) >= one_pixel * 2)
7546 -+ {
7547 -+ swap_stem ( &possible_stems[0], &possible_stems[1] );
7548 -+ valid_possible_stems = 2;
7549 -+ }
7550 -+ possible_stems[0].center = set_center_to;
7551 -+ possible_stems[0].count = stem_matches;
7552 -+ possible_stems[0].width = set_width_to;
7553 -+ possible_stems[0].height = stem_matches;
7554 -+ }
7555 -+
7556 -+ /* otherwise if there are already 2 stems */
7557 -+ else if (valid_possible_stems >= 2 )
7558 -+ {
7559 -+ /* if the stem is within the range of existing one, replace existing one */
7560 -+ if ( abs(set_center_to - possible_stems[0].center) <= one_pixel * 2)
7561 -+ {
7562 -+ possible_stems[0].center = set_center_to;
7563 -+ possible_stems[0].count = stem_matches;
7564 -+ possible_stems[0].width = set_width_to;
7565 -+ possible_stems[0].height = stem_matches;
7566 -+ }
7567 -+ /* if the stem isn't within the range of this one */
7568 -+ else
7569 -+ {
7570 -+ /* see if within range of next one and swap if so and proceed overwriting it */
7571 -+ if ( abs(set_center_to - possible_stems[1].center) <= one_pixel * 2)
7572 -+ {
7573 -+ swap_stem ( &possible_stems[0], &possible_stems[1] );
7574 -+ }
7575 -+
7576 -+ /* otherwise see if in range of third one */
7577 -+ else if ( abs(set_center_to - possible_stems[2].center) <= one_pixel * 2)
7578 -+ {
7579 -+ swap_stem ( &possible_stems[0], &possible_stems[2] );
7580 -+ }
7581 -+
7582 -+ /* otherwise this is the new top dog, so demote everything */
7583 -+ else
7584 -+ {
7585 -+ swap_stem ( &possible_stems[1], &possible_stems[2] );
7586 -+ swap_stem ( &possible_stems[0], &possible_stems[1] );
7587 -+ valid_possible_stems += 1;
7588 -+ }
7589 -+ possible_stems[0].center = set_center_to;
7590 -+ possible_stems[0].count = stem_matches;
7591 -+ possible_stems[0].width = set_width_to;
7592 -+ possible_stems[0].height = stem_matches;
7593 -+ }
7594 -+ }
7595 -+ }
7596 -+
7597 -+ else if ( stem_matches > possible_stems[1].height && set_center_to != 0)
7598 -+ {
7599 -+
7600 -+ /* make sure it doesn't match the first stem */
7601 -+ if ( abs(set_center_to - possible_stems[0].center) >= one_pixel * 2 )
7602 -+ {
7603 -+
7604 -+ /* if this is the second stem */
7605 -+ if (valid_possible_stems == 1) valid_possible_stems = 2;
7606 -+
7607 -+ /* otherwise if there is already a stem here */
7608 -+ else if (valid_possible_stems >= 2 )
7609 -+ {
7610 -+ /* if it doesn't match the second stem, proceed to swap out with the third */
7611 -+ /* if it does, replace it */
7612 -+ if ( abs(set_center_to - possible_stems[1].center) >= one_pixel * 2 )
7613 -+ {
7614 -+ swap_stem ( &possible_stems[1], &possible_stems[2] );
7615 -+ valid_possible_stems +=1;
7616 -+ }
7617 -+ }
7618 -+ possible_stems[1].center = set_center_to;
7619 -+ possible_stems[1].count = stem_matches;
7620 -+ possible_stems[1].width = set_width_to;
7621 -+ possible_stems[1].height = stem_matches;
7622 -+ }
7623 -+ }
7624 -+
7625 -+ else if ( stem_matches > possible_stems[2].height && set_center_to != 0)
7626 -+ {
7627 -+ /* if it doesn't match the first or second one */
7628 -+ if ( abs(set_center_to - possible_stems[0].center) >= one_pixel * 2
7629 -+ && abs(set_center_to - possible_stems[1].center) >= one_pixel * 2)
7630 -+
7631 -+ {
7632 -+ if (valid_possible_stems == 2)
7633 -+ {
7634 -+ valid_possible_stems += 1;
7635 -+ }
7636 -+ possible_stems[2].center = set_center_to;
7637 -+ possible_stems[2].count = stem_matches;
7638 -+ possible_stems[2].width = set_width_to;
7639 -+ possible_stems[1].height = stem_matches;
7640 -+ }
7641 -+ }
7642 -+ if (valid_possible_stems > 3) valid_possible_stems = 3;
7643 -+
7644 -+ center++;
7645 -+ }
7646 -+
7647 -+ /* promote to stem */
7648 -+ if (valid_possible_stems > 0)
7649 -+ {
7650 -+ stems[0].center = possible_stems[0].center;
7651 -+ stems[0].count = possible_stems[0].count;
7652 -+ stems[0].width = possible_stems[0].width;
7653 -+ stems[0].height = possible_stems[0].height;
7654 -+ stems[0].generated = FALSE;
7655 -+ valid_stems++;
7656 -+ }
7657 -+
7658 -+ if (valid_stems == 1 && valid_possible_stems > 1)
7659 -+ {
7660 -+ stems[1].center = possible_stems[1].center;
7661 -+ stems[1].count = possible_stems[1].count;
7662 -+ stems[1].width = possible_stems[1].width;
7663 -+ stems[1].height = possible_stems[1].height;
7664 -+ stems[1].generated = FALSE;
7665 -+ valid_stems++;
7666 -+ }
7667 -+
7668 -+ if (valid_stems == 2 && valid_possible_stems > 2 && possible_stems[2].center != 0 )
7669 -+ {
7670 -+ stems[2].center = possible_stems[2].center;
7671 -+ stems[2].count = possible_stems[2].count;
7672 -+ stems[2].width = possible_stems[2].width;
7673 -+ stems[2].height = possible_stems[2].height;
7674 -+ stems[2].generated = FALSE;
7675 -+ valid_stems++;
7676 -+ }
7677 -+
7678 -+ /* sort stems in x direction */
7679 -+ if ( valid_stems == 3)
7680 -+ {
7681 -+ if (stems[0].center > stems[1].center)
7682 -+ swap_stem ( &stems[0], &stems[1] );
7683 -+ if (stems[0].center > stems[2].center)
7684 -+ swap_stem ( &stems[1], &stems[2] );
7685 -+ if (stems[1].center > stems[2].center)
7686 -+ swap_stem ( &stems[1], &stems[2] );
7687 -+ if (stems[0].center > stems[1].center)
7688 -+ swap_stem ( &stems[0], &stems[1] );
7689 -+
7690 -+ /* only look at first and last stem for now */
7691 -+ swap_stem ( &stems[1], &stems[2] );
7692 -+ }
7693 -+
7694 -+ if (strategy_use_verdana_12_hack
7695 -+ && strcasestr(slot->face->family_name, "Verdana")
7696 -+ && ppem == 12
7697 -+ && valid_stems == 1
7698 -+ && (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4
7699 -+ ||stems[0].center + m_horiBearingX * 12 - one_pixel > m_horiAdvance * 8) )
7700 -+ {
7701 -+ if (stems[0].center + m_horiBearingX * 12 - one_pixel < m_horiAdvance * 4)
7702 -+ {
7703 -+ stems[1].center = rightmost_point - one_pixel / 2;
7704 -+ stems[1].width = 1;
7705 -+ stems[1].generated = TRUE;
7706 -+ valid_stems += 1;
7707 -+ }
7708 -+ else
7709 -+ {
7710 -+ stems[1].center = leftmost_point + one_pixel / 2;
7711 -+ stems[1].width = 1;
7712 -+ stems[1].generated = TRUE;
7713 -+ valid_stems += 1;
7714 -+ }
7715 -+ strategy_always_use_distance_ceiling = TRUE;
7716 -+ }
7717 -+
7718 -+ /* synthesize stems - Works, but needs work */
7719 -+ if ( (strategy_synthesize_stems || known_stem_values->synth_stems) && valid_stems == 0 && ppem > 10 )
7720 -+ {
7721 -+ /* 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 */
7722 -+ if (leftmost_segment_not_extrema->x1 == leftmost_point_not_extrema
7723 -+ && abs(leftmost_segment_not_extrema->x2 - leftmost_segment_not_extrema->x1)
7724 -+ < (rightmost_point_not_extrema - leftmost_point_not_extrema)/3
7725 -+ && leftmost_segment_not_extrema->y
7726 -+ < height && leftmost_segment_not_extrema->y > 1 )
7727 -+ {
7728 -+ stems[valid_stems].center = (leftmost_segment_not_extrema->x2 + leftmost_segment_not_extrema->x1) / 2;
7729 -+ stems[valid_stems].width = leftmost_segment_not_extrema->x2 - leftmost_segment_not_extrema->x1;
7730 -+ stems[valid_stems].generated = TRUE;
7731 -+ valid_stems += 1;
7732 -+ }
7733 -+
7734 -+
7735 -+ if (rightmost_segment_not_extrema->x2 == rightmost_point_not_extrema
7736 -+ && abs(rightmost_segment_not_extrema->x2 - rightmost_segment_not_extrema->x1)
7737 -+ < (rightmost_point_not_extrema - leftmost_point_not_extrema)/3
7738 -+ && rightmost_segment_not_extrema->y < height && rightmost_segment_not_extrema->y > 1 )
7739 -+ {
7740 -+ stems[valid_stems].center = (rightmost_segment_not_extrema->x2 + rightmost_segment_not_extrema->x1) / 2;
7741 -+ stems[valid_stems].width = rightmost_segment_not_extrema->x2 - rightmost_segment_not_extrema->x1;
7742 -+ stems[valid_stems].generated = TRUE;
7743 -+ valid_stems += 1;
7744 -+ }
7745 -+
7746 -+ }
7747 -+
7748 -+ /* sort stems in x direction */
7749 -+ if (valid_stems > 1 && stems[0].center > stems[1].center)
7750 -+ swap_stem ( &stems[0], &stems[1] );
7751 -+
7752 -+ if ( valid_stems == 0 && known_stem_values->stem_translating != 0 )
7753 -+ {
7754 -+ *translate_value += known_stem_values->stem_translating;
7755 -+
7756 -+ if (strategy_use_strengths )
7757 -+ {
7758 -+ /* consider 1/2 pixel the max when strength is at 100%, unless translate is already greater than that */
7759 -+ FT_Int strength_cutoff = 32;
7760 -+ if (abs(*translate_value) > strength_cutoff) strength_cutoff = *translate_value;
7761 -+ max_strength = (strength_cutoff * alignment_strength) / 100;
7762 -+ if (*translate_value < -max_strength) *translate_value = -max_strength;
7763 -+ else if (*translate_value > max_strength) *translate_value = max_strength;
7764 -+ }
7765 -+ }
7766 -+ else
7767 -+ /* Start snapping */
7768 -+ {
7769 -+ FT_Int center_offset;
7770 -+ FT_Int modulus;
7771 -+ FT_Int delta, delta2;
7772 -+ FT_Long stem_distance = 1, new_distance = 1;
7773 -+ FT_Int distance_floor, distance_ceiling;
7774 -+ FT_Int translate_value2 = 0;
7775 -+ FT_Int main_stem = 0;
7776 -+ FT_Int lbearing = m_horiBearingX * 12;
7777 -+ FT_Int bitmap_stem_location = stems[0].center;
7778 -+ FT_Int advance_stem_location = bitmap_stem_location + lbearing - one_pixel;
7779 -+ FT_Int advance_width = m_horiAdvance * 12;
7780 -+ FT_Int original_advance_width = 12 * (slot->linearHoriAdvance >> 10);
7781 -+ FT_Int glyph_width = rightmost_point - leftmost_point;
7782 -+ FT_Int stem_width = stems[0].width;
7783 -+ FT_Int advance_leftmost_location = leftmost_point + lbearing - one_pixel;
7784 -+ FT_Int advance_rightmost_location = rightmost_point + lbearing - one_pixel;
7785 -+
7786 -+#define proposed_transformed_point(point) \
7787 -+ point * (float)(new_distance) / (float)(stem_distance) \
7788 -+ + *translate_value * 12 - ( stems[main_stem].center * (float)(new_distance) \
7789 -+ / (float)(stem_distance) - stems[main_stem].center)
7790 -+
7791 -+#define proposed_translated_point(point) point + *translate_value * 12
7792 -+
7793 -+ center_offset = one_pixel / 2; /* half pixel */
7794 -+ modulus = one_pixel; /* whole pixel */
7795 -+
7796 -+ /* Determine center_offset via known values */
7797 -+ if (known_stem_values->stem_width >= 0)
7798 -+ {
7799 -+ if (known_stem_values->stem_width % 2 == 0)
7800 -+ {
7801 -+ center_offset = 0;
7802 -+ }
7803 -+ else
7804 -+ {
7805 -+ center_offset = one_pixel / 2;
7806 -+ }
7807 -+ }
7808 -+ /* otherwise do intelligent guessing, if set */
7809 -+ else if ( strategy_auto_change_center_offset
7810 -+ && ppem >= STEM_WIDTH_2_PPEM
7811 -+ && stems[0].width < one_pixel * 1.45)
7812 -+ {
7813 -+ center_offset = one_pixel / 2;
7814 -+ }
7815 -+ else if ( strategy_auto_change_center_offset
7816 -+ && ppem >= STEM_WIDTH_2_PPEM
7817 -+ && stems[0].width >= one_pixel * 1.45
7818 -+ && stems[0].width < one_pixel * 2.6)
7819 -+ {
7820 -+ center_offset = 0;
7821 -+ }
7822 -+ else if ( strategy_auto_change_center_offset
7823 -+ && ppem >= STEM_WIDTH_2_PPEM
7824 -+ && stems[0].width >= one_pixel * 2.6
7825 -+ && stems[0].width < one_pixel * 3.6)
7826 -+ {
7827 -+ center_offset = one_pixel / 2;
7828 -+ }
7829 -+ else if ( strategy_auto_change_center_offset && ppem >= STEM_WIDTH_2_PPEM )
7830 -+ center_offset = (one_pixel * ((((int)(stems[0].width + one_pixel / 2)) / one_pixel ) % 2) ) / 2;
7831 -+
7832 -+ /* Snap to closest translate and scale values by default */
7833 -+ if (valid_stems >= 1)
7834 -+ {
7835 -+ /* closest snapping point for stem 0 */
7836 -+ delta = (stems[0].center + center_offset) % (modulus);
7837 -+
7838 -+ if (delta < modulus / 2 ) *translate_value = ( - delta ) / (columns_per_pixel * 4); /* snap left */
7839 -+ else *translate_value = (modulus -delta) / (columns_per_pixel * 4); /* snap right */
7840 -+ }
7841 -+
7842 -+ if (strategy_use_d_correction)
7843 -+ {
7844 -+ /* if the only stem is in the last 1/3 of glyph width, the advance is
7845 -+ * 6 pixels, the ppem 11, and doing so doesn't violate bitmap boundaries,
7846 -+ * force it to snap right */
7847 -+ if (valid_stems == 1 && advance_stem_location > (advance_width * 2) / 3
7848 -+ && advance_width == 6 * one_pixel
7849 -+ && rightmost_point + modulus - delta <= ( width - (columns_per_pixel * 2) / 3) * 256
7850 -+ && ppem == 11
7851 -+ )
7852 -+ *translate_value = (modulus -delta) / (columns_per_pixel * 4);
7853 -+ }
7854 -+
7855 -+ if (strategy_use_strengths )
7856 -+ {
7857 -+ /* consider 1/2 pixel the max when strength is at 100%, unless translate is already greater than that */
7858 -+ FT_Int strength_cutoff = 32;
7859 -+ if (abs(*translate_value) > strength_cutoff) strength_cutoff = *translate_value;
7860 -+ max_strength = (strength_cutoff * alignment_strength) / 100;
7861 -+ if (*translate_value < -max_strength) *translate_value = -max_strength;
7862 -+ else if (*translate_value > max_strength) *translate_value = max_strength;
7863 -+ }
7864 -+
7865 -+ /* If 2 stems is detected, scale distance between in order to land on pixels */
7866 -+ if ( valid_stems >= 2)
7867 -+ {
7868 -+ stem_distance = abs(stems[1].center - stems[0].center);
7869 -+
7870 -+ delta = stem_distance % ( modulus );
7871 -+ new_distance = stem_distance - delta;
7872 -+
7873 -+ distance_floor = stem_distance - delta;
7874 -+ distance_ceiling = stem_distance + (modulus - delta);
7875 -+
7876 -+ if (delta < modulus / 2 ) new_distance = distance_floor;
7877 -+ else new_distance = distance_ceiling;
7878 -+
7879 -+ if ( columns_per_pixel == 3 && valid_stems == 3 && strategy_use_m_control && valid_stems == 3
7880 -+ && (width - 2 * columns_per_pixel) > 6 * columns_per_pixel
7881 -+ && ppem > 8
7882 -+ && (advance_stem_location - advance_leftmost_location) < stems[main_stem].width * 2 )
7883 -+ {
7884 -+ FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */
7885 -+
7886 -+ if (verbose) printf ("USING M CONTROL ");
7887 -+ distance_floor = stem_distance - stem_distance % ( modulus * mod_factor) ;
7888 -+ distance_ceiling = distance_floor + modulus * mod_factor;
7889 -+
7890 -+ new_distance = distance_ceiling;
7891 -+
7892 -+ /* force certain ideal situations */
7893 -+ /* these 2 are mostly safe to do */
7894 -+ if (distance_ceiling + one_pixel * columns_per_pixel == advance_width
7895 -+ && (stem_width < one_pixel * 1.25 ))
7896 -+ new_distance = distance_ceiling;
7897 -+ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER THAT NUDGE IS UP OR DOWN */
7898 -+ else if (stem_distance + one_pixel * 2.6 >= advance_width
7899 -+ && (stem_width < one_pixel * 1.25 ))
7900 -+ new_distance = distance_ceiling;
7901 -+
7902 -+ if (proposed_transformed_point(leftmost_point) < one_third_pixel * 2
7903 -+ || proposed_transformed_point(rightmost_point) > (width -2 ) * one_third_pixel)
7904 -+ new_distance = distance_floor;
7905 -+
7906 -+ /* NEED TO IGNORE SERIF Ms HERE */
7907 -+ /* perhaps check bitmap boundaries instead??? */
7908 -+ if (strategy_bearing_correction && new_distance == distance_ceiling)
7909 -+ {
7910 -+ /* Correct if bearings are made substantially worse (more than 1/3 a pixel beyond advance) */
7911 -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width + one_third_pixel
7912 -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location
7913 -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width
7914 -+ )
7915 -+ new_distance = distance_floor;
7916 -+ }
7917 -+
7918 -+ if ( known_stem_values->m >= 0 )
7919 -+ {
7920 -+ if ( known_stem_values->m == 0 ) new_distance = distance_floor;
7921 -+ else new_distance = distance_ceiling;
7922 -+ }
7923 -+
7924 -+ if ( (rightmost_point - leftmost_point) - ((rightmost_point * *scale_value) - (leftmost_point * *scale_value)) >= one_pixel * 1.5 )
7925 -+ {
7926 -+ *scale_value = 1.0;
7927 -+ *translate_value = 0;
7928 -+ goto Exit;
7929 -+ }
7930 -+
7931 -+ }
7932 -+ else if ( columns_per_pixel == 1 && valid_stems == 3 && strategy_use_m_control && valid_stems == 3
7933 -+ && width >= 6 * columns_per_pixel
7934 -+ && ppem > 8
7935 -+ && (advance_stem_location - advance_leftmost_location) < stems[main_stem].width * 2 )
7936 -+ {
7937 -+ FT_Int mod_factor = 2; /*Possibly use 2 only when compatible widths is on? */
7938 -+
7939 -+ if (verbose) printf ("USING M CONTROL ");
7940 -+ distance_floor = stem_distance - stem_distance % ( modulus * mod_factor) ;
7941 -+ distance_ceiling = distance_floor + modulus * mod_factor;
7942 -+
7943 -+ new_distance = distance_ceiling;
7944 -+
7945 -+ /* force certain ideal situations */
7946 -+ /* these 2 are mostly safe to do */
7947 -+ if (distance_ceiling + one_pixel * columns_per_pixel == advance_width
7948 -+ && (stem_width < one_pixel * 1.25 )) new_distance = distance_ceiling;
7949 -+ /* NEED TO FIGURE OUT A WAY TO DETERMINE WHETHER THAT NUDGE IS UP OR DOWN */
7950 -+ else if (stem_distance + one_pixel * 2.6 >= advance_width
7951 -+ && (stem_width < one_pixel * 1.25 ))
7952 -+ new_distance = distance_ceiling;
7953 -+
7954 -+ if (proposed_transformed_point(leftmost_point) < 0
7955 -+ || proposed_transformed_point(rightmost_point) > (width) * one_pixel - 2*one_third_pixel)
7956 -+ new_distance = distance_floor;
7957 -+
7958 -+ /* NEED TO IGNORE SERIF Ms HERE */
7959 -+ /* perhaps check bitmap boundaries instead??? */
7960 -+ if (strategy_bearing_correction && new_distance == distance_ceiling)
7961 -+ {
7962 -+ /* Correct if bearings are made substantially worse (more than 1/3 a pixel beyond advance) */
7963 -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width + one_third_pixel
7964 -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location
7965 -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width
7966 -+ )
7967 -+ new_distance = distance_floor;
7968 -+ }
7969 -+
7970 -+ if ( known_stem_values->m >= 0 )
7971 -+ {
7972 -+ if ( known_stem_values->m == 0 ) new_distance = distance_floor;
7973 -+ else new_distance = distance_ceiling;
7974 -+ }
7975 -+
7976 -+
7977 -+ if ( (rightmost_point - leftmost_point) - ((rightmost_point * *scale_value) - (leftmost_point * *scale_value)) >= one_pixel * 1.5 )
7978 -+ {
7979 -+ *scale_value = 1.0;
7980 -+ *translate_value = 0;
7981 -+ goto Exit;
7982 -+ }
7983 -+
7984 -+ }
7985 -+ else
7986 -+ {
7987 -+ if (strategy_fit_to_width)
7988 -+ {
7989 -+ new_distance = advance_width - 3 * one_pixel;
7990 -+ }
7991 -+ else if (known_stem_values->stem_scaling >= 0)
7992 -+ {
7993 -+ if (known_stem_values->stem_scaling > 0) new_distance = distance_ceiling;
7994 -+ else new_distance = distance_floor;
7995 -+
7996 -+ /* enforce advance width boundaries */
7997 -+ /* TOO RESTRICTIVE ON SERIF FONTS */
7998 -+ if ( proposed_transformed_point(advance_rightmost_location) >= advance_width
7999 -+ || proposed_transformed_point(advance_leftmost_location) <= 0
8000 -+ ) new_distance = distance_floor;
8001 -+
8002 -+ /* enforce literal bitmap boundaries if there is no translate room */
8003 -+ if ( ( proposed_transformed_point(rightmost_point) >= width * 256
8004 -+ || proposed_transformed_point(leftmost_point ) <= one_pixel )
8005 -+ && new_distance + one_pixel * 3 > advance_width )
8006 -+ new_distance = distance_floor;
8007 -+
8008 -+ }
8009 -+ else if (strategy_translate_using_closest_stem)
8010 -+ {
8011 -+ /* closest snapping point for stem 1 */
8012 -+ delta2 = (stems[1].center + center_offset) % (modulus);
8013 -+
8014 -+ if (delta2 < modulus / 2 ) translate_value2 = ( - delta2 ) / (columns_per_pixel * 4); /* snap left */
8015 -+ else translate_value2 = (modulus -delta2) / (columns_per_pixel * 4); /* snap right */
8016 -+
8017 -+ if (abs(translate_value2) < abs(*translate_value))
8018 -+ {
8019 -+ *translate_value = translate_value2;
8020 -+ main_stem = 1;
8021 -+ }
8022 -+
8023 -+ }
8024 -+ else if (strategy_scale_to_closest_centers)
8025 -+ {
8026 -+ /* closest snapping point for stem 0 */
8027 -+ delta = (stems[0].center + center_offset) % (modulus);
8028 -+ delta2 = (stems[1].center + center_offset) % (modulus);
8029 -+
8030 -+ if (delta < modulus / 2 ) new_distance = delta + stem_distance; /* stretch left */
8031 -+ else new_distance = delta - modulus + stem_distance; /* stretch right */
8032 -+
8033 -+ if (delta2 < modulus / 2 ) new_distance -= delta2; /* stretch left */
8034 -+ else new_distance += modulus - delta2; /* stretch right */
8035 -+
8036 -+ }
8037 -+ else if (strategy_scale_to_closest_centers_up_only)
8038 -+ {
8039 -+ FT_Int net_change = 0;
8040 -+
8041 -+ /* closest snapping point for stem 0 */
8042 -+ delta = (stems[0].center + center_offset) % (modulus);
8043 -+ delta2 = (stems[1].center + center_offset) % (modulus);
8044 -+
8045 -+ if (delta < modulus / 2 ) net_change = delta; /* stretch left */
8046 -+ else net_change = -(modulus - delta); /* stretch right */
8047 -+
8048 -+ if (delta2 < modulus / 2 ) net_change -= delta2; /* stretch left */
8049 -+ else net_change += modulus - delta2; /* stretch right */
8050 -+
8051 -+ if (net_change > 0
8052 -+ && proposed_transformed_point(advance_rightmost_location) < advance_width
8053 -+ && proposed_transformed_point(advance_leftmost_location) > 0
8054 -+ ) new_distance = distance_ceiling;
8055 -+ }
8056 -+
8057 -+ else if (strategy_always_use_distance_ceiling)
8058 -+ {
8059 -+ if ( proposed_transformed_point(advance_rightmost_location) < advance_width
8060 -+ && proposed_transformed_point(advance_leftmost_location) > 0
8061 -+ )
8062 -+ new_distance = distance_ceiling;
8063 -+ }
8064 -+ }
8065 -+
8066 -+ if (strategy_use_strengths)
8067 -+ {
8068 -+ FT_Int strength_cutoff = center_offset;
8069 -+ delta2 = new_distance - stem_distance;
8070 -+ if (abs(delta2) > strength_cutoff) strength_cutoff = delta2;
8071 -+
8072 -+ max_strength = (strength_cutoff * fitting_strength) / 100;
8073 -+ if (delta2 < -max_strength ) new_distance = stem_distance - max_strength;
8074 -+ else if (delta2 > max_strength) new_distance = stem_distance + max_strength;
8075 -+ }
8076 -+
8077 -+ *scale_value = (float)(new_distance + 0) / (float)(stem_distance + 0 );
8078 -+ *translate_value = *translate_value - ((float)(stems[main_stem].center * (float)new_distance) / (float)stem_distance - stems[main_stem].center) / 12;
8079 -
8080 -- return 0;
8081 -- }
8082 -+ if (valid_stems == 2) *embolden_value = (64.0 / *scale_value - 64.0);
8083 -+ if (valid_stems == 3) *embolden_value = (64.0 / *scale_value - 64.0) / 1.5;
8084 -+ }
8085 -
8086 -+ if (verbose) printf ("%lu stems:", valid_stems);
8087 -
8088 -- /* sets render-specific mode */
8089 -- static FT_Error
8090 -- ft_smooth_set_mode( FT_Renderer render,
8091 -- FT_ULong mode_tag,
8092 -- FT_Pointer data )
8093 -- {
8094 -- /* we simply pass it to the raster */
8095 -- return render->clazz->raster_class->raster_set_mode( render->raster,
8096 -- mode_tag,
8097 -- data );
8098 -- }
8099 -+ if (valid_stems == 1 && verbose)
8100 -+ printf ("1 stem: bitmapwidth:%d glyphwidth:%f glyph_width:%f center:%f bearing:%f advance:%f lhadvance:%f stemwidth:%f %d %d",
8101 -+ (width - 6) / columns_per_pixel,
8102 -+ (float)m_width / 64.0,
8103 -+ (float)glyph_width / (float)one_pixel,
8104 -+ (float)((float)advance_stem_location) / (float)one_pixel,
8105 -+ (float)m_horiBearingX / 64.0,
8106 -+ (float)m_horiAdvance / 64.0,
8107 -+ (float)linearHoriAdvance / 64.0,
8108 -+ (float)stems[0].width / (float)one_pixel,
8109 -+ advance_width, original_advance_width
8110 -+ );
8111 -+ else if (valid_stems >= 2 && verbose)
8112 -+ printf ("%lu stems: bitmapwidth:%d center1:%f center2:%f difference:%f bearing:%f advance:%f advstemloc:%f ",
8113 -+ valid_stems,
8114 -+ (width - 6) / columns_per_pixel,
8115 -+ ((float)advance_stem_location) / (float)one_pixel,
8116 -+ ((float)advance_stem_location + (float)abs(stems[1].center - stems[0].center)) / (float)one_pixel,
8117 -+ ((float)abs(stems[1].center - stems[0].center)) / (float)one_pixel,
8118 -+ (float)m_horiBearingX / 64.0,
8119 -+ (float)m_horiAdvance / 64.0,
8120 -+ (float)advance_stem_location / (float)one_pixel);
8121 -
8122 -- /* transform a given glyph image */
8123 -- static FT_Error
8124 -- ft_smooth_transform( FT_Renderer render,
8125 -- FT_GlyphSlot slot,
8126 -- const FT_Matrix* matrix,
8127 -- const FT_Vector* delta )
8128 -- {
8129 -- FT_Error error = Smooth_Err_Ok;
8130 -+ if (strategy_bearing_correction)
8131 -+ {
8132 -+ /* Correct if negative bearings are made substantially worse (more than 1/3 a pixel) */
8133 -+ if (proposed_transformed_point(advance_rightmost_location) > advance_width
8134 -+ && proposed_transformed_point(advance_rightmost_location) > advance_rightmost_location
8135 -+ && -proposed_transformed_point(advance_leftmost_location ) < advance_rightmost_location - advance_width
8136 -+ && *translate_value > one_third_pixel / (columns_per_pixel * 4) )
8137 -+ {
8138 -+ *translate_value -=64 ;
8139 -+ if (verbose) printf ("TRANSLATING -64 ");
8140 -+ }
8141 -+ }
8142 -
8143 -+ if ( strategy_use_verdana_12_hack
8144 -+ && strcasestr(slot->face->family_name, "Verdana")
8145 -+ && ppem == 12
8146 -+ && *scale_value == 1.0 && valid_stems == 0
8147 -+ && height < 8
8148 -+ && advance_rightmost_location * 1.1 < advance_width )
8149 -+ *scale_value = 1.1;
8150 -
8151 -- if ( slot->format != render->glyph_format )
8152 -- {
8153 -- error = Smooth_Err_Invalid_Argument;
8154 - goto Exit;
8155 -+
8156 - }
8157 -
8158 -- if ( matrix )
8159 -- FT_Outline_Transform( &slot->outline, matrix );
8160 -+ Exit:
8161 -
8162 -- if ( delta )
8163 -- FT_Outline_Translate( &slot->outline, delta->x, delta->y );
8164 -+#define transformed_point( point ) point * *scale_value + *translate_value * 12
8165 -+
8166 -+ if (strategy_correct_out_of_bounds_outlines)
8167 -+ {
8168 -+ /* Correct if outside bitmap */
8169 -+ if (transformed_point(rightmost_point) >= width * 256 - 2 * one_third_pixel
8170 -+ && transformed_point(leftmost_point ) > one_pixel + 2 * one_third_pixel )
8171 -+ {
8172 -+ *translate_value -=64 ;
8173 -+ }
8174 -+ else if (transformed_point(leftmost_point) <= one_pixel / 2
8175 -+ && transformed_point(rightmost_point ) <= width * 256 -(one_pixel + one_pixel / 2) )
8176 -+ {
8177 -+ *translate_value += 64;
8178 -+ }
8179 -+ }
8180 -+
8181 -+ STVALUES
8182 -+
8183 -+ free(segments);
8184 -+ free(leftmost_segment);
8185 -+ free(rightmost_segment);
8186 -+
8187 -+ free(known_stem_values);
8188 -+ free(stems);
8189 -+ free(possible_stems);
8190 -+ free(leftmost_stem);
8191 -+ free(rightmost_stem);
8192 -+
8193 -+ free(centers);
8194 -
8195 -- Exit:
8196 -- return error;
8197 - }
8198 -
8199 -
8200 -- /* return the glyph's control box */
8201 -+ /* Gamma correction */
8202 - static void
8203 -- ft_smooth_get_cbox( FT_Renderer render,
8204 -- FT_GlyphSlot slot,
8205 -- FT_BBox* cbox )
8206 -+ _ft_lcd_gamma_correction_correction ( FT_Bitmap* bitmap,
8207 -+ FT_Render_Mode mode,
8208 -+ FT_GlyphSlot slot,
8209 -+ float gamma_correction_lt,
8210 -+ float gamma_correction_value)
8211 - {
8212 -- FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
8213 --
8214 -- if ( slot->format == render->glyph_format )
8215 -- FT_Outline_Get_CBox( &slot->outline, cbox );
8216 -+ if ( gamma_correction_value != 1.0 )
8217 -+ {
8218 -+ FT_UInt width = (FT_UInt)bitmap->width;
8219 -+ FT_UInt height = (FT_UInt)bitmap->rows;
8220 -+ FT_Byte* line = bitmap->buffer;
8221 -+ float ppem = (float)slot->face->size->metrics.x_ppem;
8222 -+
8223 -+ if ( !slot->face || !slot->face->size ) return;
8224 -+
8225 -+ if (ppem >= 5 )
8226 -+ for (height = (FT_UInt)bitmap->rows; height > 0; height--, line += bitmap->pitch )
8227 -+ {
8228 -+ FT_UInt xx;
8229 -+
8230 -+ for ( xx = 0; xx < width; xx += 1 )
8231 -+ {
8232 -+ /*normal*/
8233 -+ /*line[xx] = gamma2 ( line[xx], gamma_correction_value );*/
8234 -+
8235 -+ /* sloped */
8236 -+ /*line[xx] = gamma2 ( line[xx], gamma_correction_value - 5
8237 -+ * (1-gamma_correction_value)/(gamma_correction_lt -5)
8238 -+ + ((1-gamma_correction_value)/(gamma_correction_lt -5)) * ppem );*/
8239 -+
8240 -+ /* 1/3-sloped */
8241 -+ line[xx] = gamma2 ( line[xx], gamma_correction_value - 5
8242 -+ * ((1-gamma_correction_value)/(3*(gamma_correction_lt -5)))
8243 -+ * + ((1-gamma_correction_value)/(3*(gamma_correction_lt -5))) * ppem );
8244 -+ }
8245 -+ }
8246 -+ }
8247 - }
8248 -
8249 -+#endif
8250 -+
8251 -
8252 - /* convert a slot's glyph image into a bitmap */
8253 - static FT_Error
8254 -@@ -104,19 +2871,406 @@
8255 - {
8256 - FT_Error error;
8257 - FT_Outline* outline = NULL;
8258 -+ FT_Outline* outline_orig = NULL;
8259 - FT_BBox cbox;
8260 -- FT_Pos width, height, pitch;
8261 -+ FT_Pos width=0, height=0, pitch=0, ppem;
8262 - #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
8263 - FT_Pos height_org, width_org;
8264 - #endif
8265 -- FT_Bitmap* bitmap;
8266 -- FT_Memory memory;
8267 -+ FT_Bitmap* bitmap = 0;
8268 -+ FT_Memory memory = 0;
8269 - FT_Int hmul = mode == FT_RENDER_MODE_LCD;
8270 - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V;
8271 -- FT_Pos x_shift, y_shift, x_left, y_top;
8272 -+ FT_Pos x_shift = 0, y_shift = 0, x_left = 0, y_top = 0;
8273 -
8274 - FT_Raster_Params params;
8275 -
8276 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8277 -+ FT_Matrix scaleMat;
8278 -+ FT_Long translate_value = 0;
8279 -+ float scale_value = 1.0;
8280 -+ FT_Int align_called = 0;
8281 -+
8282 -+
8283 -+ int chromeos_style_sharpening_strength = 0;
8284 -+ int checked_chromeos_style_sharpening_strength = 0;
8285 -+ int alignment_strength = 0;
8286 -+ int fitting_strength = 0;
8287 -+ FT_UInt checked_alignment_strength = 0;
8288 -+ FT_UInt checked_fitting_strength = 0;
8289 -+ FT_UInt checked_fringe_filter_strength = 0;
8290 -+ int fringe_filter_strength = 0;
8291 -+ FT_UInt checked_grayscale_filter_strength = 0;
8292 -+ int grayscale_filter_strength = 0;
8293 -+
8294 -+ FT_UInt checked_autohint_horizontal_stem_darken_strength = 0;
8295 -+ int autohint_horizontal_stem_darken_strength = 0;
8296 -+
8297 -+ FT_UInt checked_autohint_vertical_stem_darken_strength = 0;
8298 -+ int autohint_vertical_stem_darken_strength = 0;
8299 -+
8300 -+ int windows_style_sharpening_strength = 0;
8301 -+ FT_UInt checked_windows_style_sharpening_strength = 0;
8302 -+ float gamma_correction_value = 1;
8303 -+ float gamma_correction_lt = 0;
8304 -+ FT_UInt checked_gamma_correction_value = 0;
8305 -+
8306 -+ FT_Int brightness_value = 0.0;
8307 -+ FT_UInt checked_brightness_value = 0;
8308 -+
8309 -+ FT_Int contrast_value = 0.0;
8310 -+ FT_UInt checked_contrast_value = 0;
8311 -+
8312 -+ FT_Int snapping_sliding_scale_value = 0;
8313 -+ FT_UInt checked_snapping_sliding_scale_value = 0;
8314 -+
8315 -+ FT_Int global_embolden_x_value = 0;
8316 -+ FT_UInt checked_global_embolden_x_value = 0;
8317 -+
8318 -+ FT_Int global_embolden_y_value = 0;
8319 -+ FT_UInt checked_global_embolden_y_value = 0;
8320 -+
8321 -+ FT_Int bold_embolden_x_value = 0;
8322 -+ FT_UInt checked_bold_embolden_x_value = 0;
8323 -+
8324 -+ FT_Int bold_embolden_y_value = 0;
8325 -+ FT_UInt checked_bold_embolden_y_value = 0;
8326 -+
8327 -+ FT_Byte chromeos_cutoff;
8328 -+ double chromeos_gamma_value;
8329 -+
8330 -+ float embolden_value = 0.0;
8331 -+ FT_Bool autohinted = FALSE;
8332 -+
8333 -+ FT_UInt autohint_minimum_stem_height = 0;
8334 -+ FT_UInt checked_autohint_minimum_stem_height = 0;
8335 -+
8336 -+ int checked_use_various_tweaks_env = 0;
8337 -+ FT_Bool use_various_tweaks = FALSE;
8338 -+
8339 -+ int cur_width;
8340 -+ char *cur_width_env = getenv( "CUR_WIDTH" );
8341 -+
8342 -+ const FT_Int MIN_PPEM = 1;
8343 -+ /*const FT_Int MAX_PPEM = 100; */
8344 -+
8345 -+ int checked_use_known_settings_on_selected_fonts_env = 0;
8346 -+ FT_Bool use_known_settings_on_selected_fonts = FALSE;
8347 -+
8348 -+ if ( slot->face && slot->face->size && slot->face->size->metrics.x_ppem )
8349 -+ ppem = slot->face->size->metrics.x_ppem;
8350 -+ else ppem = 0;
8351 -+
8352 -+ if ( cur_width_env != NULL ){
8353 -+ sscanf ( cur_width_env, "%d", &cur_width );
8354 -+ if (cur_width != 0) autohinted = TRUE;
8355 -+ }
8356 -+
8357 -+ if ( checked_use_known_settings_on_selected_fonts_env == 0 )
8358 -+ {
8359 -+ char *use_known_settings_on_selected_fonts_env = getenv( "INFINALITY_FT_USE_KNOWN_SETTINGS_ON_SELECTED_FONTS" );
8360 -+ if ( use_known_settings_on_selected_fonts_env != NULL )
8361 -+ {
8362 -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "default" ) != 0 )
8363 -+ {
8364 -+ if ( strcasecmp(use_known_settings_on_selected_fonts_env, "true") == 0)
8365 -+ use_known_settings_on_selected_fonts = TRUE;
8366 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "1") == 0)
8367 -+ use_known_settings_on_selected_fonts = TRUE;
8368 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "on") == 0)
8369 -+ use_known_settings_on_selected_fonts = TRUE;
8370 -+ else if ( strcasecmp(use_known_settings_on_selected_fonts_env, "yes") == 0)
8371 -+ use_known_settings_on_selected_fonts = TRUE;
8372 -+ }
8373 -+ }
8374 -+ checked_use_known_settings_on_selected_fonts_env = 1;
8375 -+ }
8376 -+
8377 -+ if ( checked_use_various_tweaks_env == 0 )
8378 -+ {
8379 -+ char *use_various_tweaks_env = getenv( "INFINALITY_FT_USE_VARIOUS_TWEAKS" );
8380 -+ if ( use_various_tweaks_env != NULL )
8381 -+ {
8382 -+ if ( strcasecmp(use_various_tweaks_env, "default" ) != 0 )
8383 -+ {
8384 -+ if ( strcasecmp(use_various_tweaks_env, "true") == 0)
8385 -+ use_various_tweaks = TRUE;
8386 -+ else if ( strcasecmp(use_various_tweaks_env, "1") == 0)
8387 -+ use_various_tweaks = TRUE;
8388 -+ else if ( strcasecmp(use_various_tweaks_env, "on") == 0)
8389 -+ use_various_tweaks = TRUE;
8390 -+ else if ( strcasecmp(use_various_tweaks_env, "yes") == 0)
8391 -+ use_various_tweaks = TRUE;
8392 -+ }
8393 -+ }
8394 -+ checked_use_various_tweaks_env = 1;
8395 -+ }
8396 -+
8397 -+ if ( checked_autohint_minimum_stem_height == 0)
8398 -+ {
8399 -+ char *autohint_minimum_stem_height_env = getenv( "INFINALITY_FT_AUTOHINT_MINIMUM_STEM_WIDTH" );
8400 -+ if ( autohint_minimum_stem_height_env != NULL )
8401 -+ {
8402 -+ sscanf ( autohint_minimum_stem_height_env, "%u", &autohint_minimum_stem_height );
8403 -+ if (autohint_minimum_stem_height > 100 ) autohint_minimum_stem_height = 100;
8404 -+ else if (autohint_minimum_stem_height < 0 ) autohint_minimum_stem_height = 0;
8405 -+ }
8406 -+ checked_autohint_minimum_stem_height = 1;
8407 -+ }
8408 -+
8409 -+ if ( checked_snapping_sliding_scale_value == 0)
8410 -+ {
8411 -+ char *snapping_sliding_scale_env = getenv ( "INFINALITY_FT_STEM_SNAPPING_SLIDING_SCALE" );
8412 -+ if ( snapping_sliding_scale_env != NULL )
8413 -+ {
8414 -+ sscanf ( snapping_sliding_scale_env, "%d", &snapping_sliding_scale_value );
8415 -+ if (snapping_sliding_scale_value > MAX_PPEM ) snapping_sliding_scale_value = 0;
8416 -+ else if (snapping_sliding_scale_value < 0 ) snapping_sliding_scale_value = 0;
8417 -+
8418 -+ if (snapping_sliding_scale_value < 11 && snapping_sliding_scale_value > 0 ) snapping_sliding_scale_value = 11;
8419 -+ }
8420 -+ checked_snapping_sliding_scale_value = 1;
8421 -+ }
8422 -+
8423 -+ if ( checked_alignment_strength == 0)
8424 -+ {
8425 -+ char *alignment_strength_env = getenv ( "INFINALITY_FT_STEM_ALIGNMENT_STRENGTH" );
8426 -+ if ( alignment_strength_env != NULL )
8427 -+ {
8428 -+ sscanf ( alignment_strength_env, "%d", &alignment_strength );
8429 -+ if (alignment_strength > 100 ) alignment_strength = 100;
8430 -+ else if (alignment_strength < 0 ) alignment_strength = 0;
8431 -+ }
8432 -+ if (alignment_strength > 100 ) alignment_strength = 100;
8433 -+ checked_alignment_strength = 1;
8434 -+ if (snapping_sliding_scale_value != 0)
8435 -+ alignment_strength = sliding_scale ( 10, snapping_sliding_scale_value, alignment_strength, 100, ppem);
8436 -+ }
8437 -+
8438 -+ if ( checked_fitting_strength == 0)
8439 -+ {
8440 -+ char *fitting_strength_env = getenv( "INFINALITY_FT_STEM_FITTING_STRENGTH" );
8441 -+ if ( fitting_strength_env != NULL )
8442 -+ {
8443 -+ sscanf ( fitting_strength_env, "%d", &fitting_strength );
8444 -+ if (fitting_strength > 100 ) fitting_strength = 100;
8445 -+ else if (fitting_strength < 0 ) fitting_strength = 0;
8446 -+ }
8447 -+ if (fitting_strength > 100 ) fitting_strength = 100;
8448 -+ checked_fitting_strength = 1;
8449 -+ if (snapping_sliding_scale_value != 0)
8450 -+ fitting_strength = sliding_scale ( 10, snapping_sliding_scale_value, fitting_strength, 100, ppem);
8451 -+ }
8452 -+
8453 -+ if ( checked_chromeos_style_sharpening_strength == 0)
8454 -+ {
8455 -+ char *chromeos_style_sharpening_strength_env = getenv( "INFINALITY_FT_CHROMEOS_STYLE_SHARPENING_STRENGTH" );
8456 -+ if ( chromeos_style_sharpening_strength_env != NULL )
8457 -+ {
8458 -+ sscanf ( chromeos_style_sharpening_strength_env, "%d", &chromeos_style_sharpening_strength );
8459 -+ if (chromeos_style_sharpening_strength > 100 )
8460 -+ chromeos_style_sharpening_strength = 100;
8461 -+ else if (chromeos_style_sharpening_strength < 0 )
8462 -+ chromeos_style_sharpening_strength = 0;
8463 -+ }
8464 -+ if (ppem > 10)
8465 -+ chromeos_style_sharpening_strength =
8466 -+ (chromeos_style_sharpening_strength * ppem) / 10;
8467 -+ if (chromeos_style_sharpening_strength > 100 )
8468 -+ chromeos_style_sharpening_strength = 100;
8469 -+ checked_chromeos_style_sharpening_strength = 1;
8470 -+ }
8471 -+
8472 -+
8473 -+ if ( checked_brightness_value == 0)
8474 -+ {
8475 -+ char *brightness_env = getenv( "INFINALITY_FT_BRIGHTNESS" );
8476 -+ if ( brightness_env != NULL )
8477 -+ {
8478 -+ sscanf ( brightness_env, "%d", &brightness_value );
8479 -+ if (brightness_value > 100 )
8480 -+ brightness_value = 100;
8481 -+ else if (brightness_value < -100 )
8482 -+ brightness_value = 0;
8483 -+ }
8484 -+ checked_brightness_value = 1;
8485 -+ }
8486 -+
8487 -+ if ( checked_contrast_value == 0)
8488 -+ {
8489 -+ char *contrast_env = getenv( "INFINALITY_FT_CONTRAST" );
8490 -+ if ( contrast_env != NULL )
8491 -+ {
8492 -+ sscanf ( contrast_env, "%d", &contrast_value );
8493 -+ if (contrast_value > 100 )
8494 -+ contrast_value = 100;
8495 -+ else if (contrast_value < -100 )
8496 -+ contrast_value = 100;
8497 -+ }
8498 -+ checked_contrast_value = 1;
8499 -+ }
8500 -+
8501 -+ if ( checked_windows_style_sharpening_strength == 0)
8502 -+ {
8503 -+ char *windows_style_sharpening_strength_env = getenv( "INFINALITY_FT_WINDOWS_STYLE_SHARPENING_STRENGTH" );
8504 -+ if ( windows_style_sharpening_strength_env != NULL )
8505 -+ {
8506 -+ sscanf ( windows_style_sharpening_strength_env, "%d", &windows_style_sharpening_strength );
8507 -+ if (windows_style_sharpening_strength > 100 ) windows_style_sharpening_strength = 100;
8508 -+ else if (windows_style_sharpening_strength < 0 ) windows_style_sharpening_strength = 0;
8509 -+ }
8510 -+ /* Decrease the effect slightly in order to have a more linear increase in sharpness */
8511 -+ windows_style_sharpening_strength =
8512 -+ (( windows_style_sharpening_strength * windows_style_sharpening_strength ) / 100 + windows_style_sharpening_strength) / 2;
8513 -+ checked_windows_style_sharpening_strength = 1;
8514 -+ }
8515 -+
8516 -+ if ( checked_gamma_correction_value == 0 )
8517 -+ {
8518 -+ char *gamma_correction_value_env = getenv( "INFINALITY_FT_GAMMA_CORRECTION" );
8519 -+ if ( gamma_correction_value_env != NULL )
8520 -+ {
8521 -+ float f1, f2;
8522 -+
8523 -+ if ( strcasecmp(gamma_correction_value_env, "default" ) != 0)
8524 -+ {
8525 -+ sscanf ( gamma_correction_value_env, "%f %f", &f1, &f2 );
8526 -+ gamma_correction_lt = f1;
8527 -+ gamma_correction_value = f2 / 100.0;
8528 -+ }
8529 -+ if ( gamma_correction_value < .01 ) gamma_correction_value = 1.0;
8530 -+ }
8531 -+ checked_gamma_correction_value = 1;
8532 -+ }
8533 -+
8534 -+ /* set gamma value to 1 if out of range */
8535 -+ if ( slot->face && slot->face->size && slot->face->size->metrics.x_ppem )
8536 -+ {
8537 -+ if ( slot->face->size->metrics.x_ppem >= gamma_correction_lt )
8538 -+ {
8539 -+ gamma_correction_value = 1;
8540 -+ }
8541 -+ }
8542 -+ else gamma_correction_value = 1;
8543 -+
8544 -+
8545 -+ if ( checked_fringe_filter_strength == 0)
8546 -+ {
8547 -+ char *fringe_filter_strength_env = getenv( "INFINALITY_FT_FRINGE_FILTER_STRENGTH" );
8548 -+ if ( fringe_filter_strength_env != NULL )
8549 -+ {
8550 -+ sscanf ( fringe_filter_strength_env, "%d", &fringe_filter_strength );
8551 -+ if (fringe_filter_strength > 100 ) fringe_filter_strength = 100;
8552 -+ else if (fringe_filter_strength < 0 ) fringe_filter_strength = 0;
8553 -+ }
8554 -+ checked_fringe_filter_strength = 1;
8555 -+ }
8556 -+
8557 -+
8558 -+ if ( checked_grayscale_filter_strength == 0)
8559 -+ {
8560 -+ char *grayscale_filter_strength_env = getenv( "INFINALITY_FT_GRAYSCALE_FILTER_STRENGTH" );
8561 -+ if ( grayscale_filter_strength_env != NULL )
8562 -+ {
8563 -+ sscanf ( grayscale_filter_strength_env, "%d", &grayscale_filter_strength );
8564 -+ if (grayscale_filter_strength > 100 ) grayscale_filter_strength = 100;
8565 -+ else if (grayscale_filter_strength < 0 ) grayscale_filter_strength = 0;
8566 -+ }
8567 -+ checked_grayscale_filter_strength = 1;
8568 -+ }
8569 -+
8570 -+
8571 -+ if ( checked_autohint_horizontal_stem_darken_strength == 0)
8572 -+ {
8573 -+ char *autohint_horizontal_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_HORIZONTAL_STEM_DARKEN_STRENGTH" );
8574 -+ if ( autohint_horizontal_stem_darken_strength_env != NULL )
8575 -+ {
8576 -+ sscanf ( autohint_horizontal_stem_darken_strength_env, "%d", &autohint_horizontal_stem_darken_strength );
8577 -+ if (autohint_horizontal_stem_darken_strength > 100 ) autohint_horizontal_stem_darken_strength = 100;
8578 -+ else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_horizontal_stem_darken_strength = 0;
8579 -+ }
8580 -+ checked_autohint_horizontal_stem_darken_strength = 1;
8581 -+ }
8582 -+
8583 -+ if ( checked_autohint_vertical_stem_darken_strength == 0)
8584 -+ {
8585 -+ char *autohint_vertical_stem_darken_strength_env = getenv( "INFINALITY_FT_AUTOHINT_VERTICAL_STEM_DARKEN_STRENGTH" );
8586 -+ if ( autohint_vertical_stem_darken_strength_env != NULL )
8587 -+ {
8588 -+ sscanf ( autohint_vertical_stem_darken_strength_env, "%d", &autohint_vertical_stem_darken_strength );
8589 -+ if (autohint_vertical_stem_darken_strength > 100 ) autohint_vertical_stem_darken_strength = 100;
8590 -+ else if (autohint_horizontal_stem_darken_strength < 0 ) autohint_vertical_stem_darken_strength = 0;
8591 -+ }
8592 -+ checked_autohint_vertical_stem_darken_strength = 1;
8593 -+ }
8594 -+
8595 -+ if ( checked_global_embolden_x_value == 0)
8596 -+ {
8597 -+ char *global_embolden_x_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_X_VALUE" );
8598 -+ if ( global_embolden_x_env != NULL )
8599 -+ {
8600 -+ sscanf ( global_embolden_x_env, "%d", &global_embolden_x_value );
8601 -+ if (global_embolden_x_value > 128 ) global_embolden_x_value = 128;
8602 -+ else if (global_embolden_x_value < -128 ) global_embolden_x_value = -128;
8603 -+ }
8604 -+ checked_global_embolden_x_value = 1;
8605 -+ }
8606 -+
8607 -+ if ( checked_global_embolden_y_value == 0)
8608 -+ {
8609 -+ char *global_embolden_y_env = getenv ( "INFINALITY_FT_GLOBAL_EMBOLDEN_Y_VALUE" );
8610 -+ if ( global_embolden_y_env != NULL )
8611 -+ {
8612 -+ sscanf ( global_embolden_y_env, "%d", &global_embolden_y_value );
8613 -+ if (global_embolden_y_value > 128 ) global_embolden_y_value = 128;
8614 -+ else if (global_embolden_y_value < -128 ) global_embolden_y_value = -128;
8615 -+ }
8616 -+ checked_global_embolden_y_value = 1;
8617 -+ }
8618 -+
8619 -+
8620 -+ if ( checked_bold_embolden_x_value == 0)
8621 -+ {
8622 -+ char *bold_embolden_x_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_X_VALUE" );
8623 -+ if ( bold_embolden_x_env != NULL )
8624 -+ {
8625 -+ sscanf ( bold_embolden_x_env, "%d", &bold_embolden_x_value );
8626 -+ if (bold_embolden_x_value > 128 ) bold_embolden_x_value = 128;
8627 -+ else if (bold_embolden_x_value < -128 ) bold_embolden_x_value = -128;
8628 -+
8629 -+ }
8630 -+ checked_bold_embolden_x_value = 1;
8631 -+ }
8632 -+
8633 -+ if ( checked_bold_embolden_y_value == 0)
8634 -+ {
8635 -+ char *bold_embolden_y_env = getenv ( "INFINALITY_FT_BOLD_EMBOLDEN_Y_VALUE" );
8636 -+ if ( bold_embolden_y_env != NULL )
8637 -+ {
8638 -+ sscanf ( bold_embolden_y_env, "%d", &bold_embolden_y_value );
8639 -+ if (bold_embolden_y_value > 128 ) bold_embolden_y_value = 128;
8640 -+ else if (bold_embolden_y_value < -128 ) bold_embolden_y_value = -128;
8641 -+
8642 -+ }
8643 -+ checked_bold_embolden_y_value = 1;
8644 -+ }
8645 -+
8646 -+
8647 -+
8648 -+ if( use_various_tweaks && slot->face && slot->face->style_name )
8649 -+ {
8650 -+ /* needs to also check for artifical italics */
8651 -+ if ( strcasestr(slot->face->style_name, "Italic")
8652 -+ || strcasestr(slot->face->style_name, "Oblique") )
8653 -+ {
8654 -+ windows_style_sharpening_strength = 0;
8655 -+ chromeos_style_sharpening_strength = 0;
8656 -+ }
8657 -+ }
8658 -+
8659 -+ /*if (fitting_strength == 100) scale_value = 1.1;*/
8660 -+
8661 -+#endif
8662 -
8663 - /* check glyph image format */
8664 - if ( slot->format != render->glyph_format )
8665 -@@ -129,92 +3283,174 @@
8666 - if ( mode != required_mode )
8667 - return Smooth_Err_Cannot_Render_Glyph;
8668 -
8669 -- outline = &slot->outline;
8670 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8671 -+RERENDER:
8672 -+ if (align_called == 1){
8673 -
8674 -- /* translate the outline to the new origin if needed */
8675 -- if ( origin )
8676 -- FT_Outline_Translate( outline, origin->x, origin->y );
8677 -+ scaleMat.xx = FT_FixedFromFloat(scale_value);
8678 -+ scaleMat.xy = 0;
8679 -+ scaleMat.yx = 0;
8680 -+ scaleMat.yy = (1 << 16);
8681 -
8682 -- /* compute the control box, and grid fit it */
8683 -- FT_Outline_Get_CBox( outline, &cbox );
8684 -+ FT_Outline_Copy(outline_orig, outline);
8685 -
8686 -- cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
8687 -- cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
8688 -- cbox.xMax = FT_PIX_CEIL( cbox.xMax );
8689 -- cbox.yMax = FT_PIX_CEIL( cbox.yMax );
8690 --
8691 -- if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )
8692 -- {
8693 -- FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
8694 -- " xMin = %d, xMax = %d\n",
8695 -- cbox.xMin >> 6, cbox.xMax >> 6 ));
8696 -- return Smooth_Err_Raster_Overflow;
8697 -- }
8698 -- else
8699 -- width = ( cbox.xMax - cbox.xMin ) >> 6;
8700 -+ if (scale_value != 1.0)
8701 -+ FT_Outline_Transform( outline, &scaleMat );
8702 -
8703 -- if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
8704 -- {
8705 -- FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
8706 -- " yMin = %d, yMax = %d\n",
8707 -- cbox.yMin >> 6, cbox.yMax >> 6 ));
8708 -- return Smooth_Err_Raster_Overflow;
8709 -+ FT_Outline_Translate( outline, translate_value+0, 0 );
8710 -+
8711 -+ FT_Outline_EmboldenXY( outline, embolden_value, 0 );
8712 - }
8713 - else
8714 -- height = ( cbox.yMax - cbox.yMin ) >> 6;
8715 --
8716 -- bitmap = &slot->bitmap;
8717 -- memory = render->root.memory;
8718 --
8719 --#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
8720 -- width_org = width;
8721 -- height_org = height;
8722 -+ {
8723 - #endif
8724 -+ outline = &slot->outline;
8725 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8726 -+ /* Need to get this PRIOR to embolden, otherwise bad things happen */
8727 -+ FT_Outline_Get_CBox( outline, &cbox );
8728 -+
8729 -+ /* Various hacks that need to be turned into a new rule set */
8730 -+ /*if ( !autohinted
8731 -+ && use_known_settings_on_selected_fonts
8732 -+ && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name
8733 -+ && ( strcasestr(slot->face->family_name, "Courier New" )
8734 -+ && ( strcasestr(slot->face->style_name, "Regular" )
8735 -+ || strcasestr(slot->face->style_name, "Italic" ) ) ) )
8736 -+ FT_Outline_Embolden( outline, 24 );*/
8737 -+
8738 -+ if (!autohinted
8739 -+ && use_known_settings_on_selected_fonts
8740 -+ && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name
8741 -+ && strcasestr(slot->face->family_name, "Times New Roman" )
8742 -+ && strcasestr(slot->face->style_name, "Italic" ) )
8743 -+ FT_Outline_EmboldenXY( outline, 12, 0 );
8744 -+
8745 -+ if ( use_known_settings_on_selected_fonts
8746 -+ && autohinted && mode == FT_RENDER_MODE_LCD && slot->face->family_name && slot->face->style_name
8747 -+ && strcasestr(slot->face->family_name, "FreeSerif" )
8748 -+ && strcasestr(slot->face->style_name, "Italic" ) )
8749 -+ FT_Outline_EmboldenXY( outline, 8, 0 );
8750 -+
8751 -+ if( global_embolden_x_value != 0 || global_embolden_y_value != 0 )
8752 -+ FT_Outline_EmboldenXY( outline, global_embolden_x_value, global_embolden_y_value );
8753 -+
8754 -+ if( (bold_embolden_x_value != 0 || bold_embolden_y_value != 0)
8755 -+ && (slot->face->style_name
8756 -+ && ( strcasestr(slot->face->style_name, "Bold")
8757 -+ || strcasestr(slot->face->style_name, "Black") )
8758 -+ || ( slot->face->style_flags
8759 -+ && slot->face->style_flags & FT_STYLE_FLAG_BOLD ) ) )
8760 -+ FT_Outline_EmboldenXY( outline, bold_embolden_x_value, bold_embolden_y_value );
8761 -
8762 -- /* release old bitmap buffer */
8763 -- if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
8764 -- {
8765 -- FT_FREE( bitmap->buffer );
8766 -- slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
8767 -+ FT_Outline_Copy(outline, outline_orig);
8768 - }
8769 -
8770 -- /* allocate new one */
8771 -- pitch = width;
8772 -- if ( hmul )
8773 -+ /* translate the outline to the new origin if needed */
8774 -+ if (align_called == 0)
8775 - {
8776 -- width = width * 3;
8777 -- pitch = FT_PAD_CEIL( width, 4 );
8778 -- }
8779 -+ FT_Pos enlarge_cbox = 0;
8780 -
8781 -- if ( vmul )
8782 -- height *= 3;
8783 -+ /* enlarge for grayscale rendering */
8784 -+ if ( mode == FT_RENDER_MODE_NORMAL ) enlarge_cbox = 64;
8785 -
8786 -- x_shift = (FT_Int) cbox.xMin;
8787 -- y_shift = (FT_Int) cbox.yMin;
8788 -- x_left = (FT_Int)( cbox.xMin >> 6 );
8789 -- y_top = (FT_Int)( cbox.yMax >> 6 );
8790 -+ if ( origin )
8791 -+ FT_Outline_Translate( outline, origin->x, origin->y );
8792 -
8793 --#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
8794 -+ /* compute the control box, and grid fit it */
8795 -+ /*FT_Outline_Get_CBox( outline, &cbox );*/
8796 -+
8797 -+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin - enlarge_cbox );
8798 -+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
8799 -+ cbox.xMax = FT_PIX_CEIL( cbox.xMax + enlarge_cbox );
8800 -+ cbox.yMax = FT_PIX_CEIL( cbox.yMax );
8801 -+#else
8802 -+ if ( origin )
8803 -+ FT_Outline_Translate( outline, origin->x, origin->y );
8804 -+
8805 -+ /* compute the control box, and grid fit it */
8806 -+ FT_Outline_Get_CBox( outline, &cbox );
8807 -+
8808 -+ cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
8809 -+ cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
8810 -+ cbox.xMax = FT_PIX_CEIL( cbox.xMax );
8811 -+ cbox.yMax = FT_PIX_CEIL( cbox.yMax );
8812 -+#endif
8813 -
8814 -- if ( slot->library->lcd_filter_func )
8815 -- {
8816 -- FT_Int extra = slot->library->lcd_extra;
8817 -+ if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )
8818 -+ {
8819 -+ FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
8820 -+ " xMin = %d, xMax = %d\n",
8821 -+ cbox.xMin >> 6, cbox.xMax >> 6 ));
8822 -+ return Smooth_Err_Raster_Overflow;
8823 -+ }
8824 -+ else
8825 -+ width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
8826 -+
8827 -+ if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
8828 -+ {
8829 -+ FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
8830 -+ " yMin = %d, yMax = %d\n",
8831 -+ cbox.yMin >> 6, cbox.yMax >> 6 ));
8832 -+ return Smooth_Err_Raster_Overflow;
8833 -+ }
8834 -+ else
8835 -+ height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
8836 -
8837 -+ bitmap = &slot->bitmap;
8838 -+ memory = render->root.memory;
8839 -
8840 -+#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
8841 -+ width_org = width;
8842 -+ height_org = height;
8843 -+#endif
8844 -+
8845 -+ /* release old bitmap buffer */
8846 -+ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
8847 -+ {
8848 -+ FT_FREE( bitmap->buffer );
8849 -+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
8850 -+ }
8851 -+
8852 -+ /* allocate new one */
8853 -+ pitch = width;
8854 - if ( hmul )
8855 - {
8856 -- x_shift -= 64 * ( extra >> 1 );
8857 -- width += 3 * extra;
8858 -- pitch = FT_PAD_CEIL( width, 4 );
8859 -- x_left -= extra >> 1;
8860 -+ width = width * 3;
8861 -+ pitch = FT_PAD_CEIL( width, 4 );
8862 - }
8863 -
8864 - if ( vmul )
8865 -+ height *= 3;
8866 -+
8867 -+ x_shift = (FT_Int) cbox.xMin;
8868 -+ y_shift = (FT_Int) cbox.yMin;
8869 -+ x_left = (FT_Int)( cbox.xMin >> 6 );
8870 -+ y_top = (FT_Int)( cbox.yMax >> 6 );
8871 -+
8872 -+#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
8873 -+
8874 -+ if ( slot->library->lcd_filter_func )
8875 - {
8876 -- y_shift -= 64 * ( extra >> 1 );
8877 -- height += 3 * extra;
8878 -- y_top += extra >> 1;
8879 -+ FT_Int extra = slot->library->lcd_extra;
8880 -+
8881 -+
8882 -+ if ( hmul )
8883 -+ {
8884 -+ x_shift -= 64 * ( extra >> 1 );
8885 -+ width += 3 * extra;
8886 -+ pitch = FT_PAD_CEIL( width, 4 );
8887 -+ x_left -= extra >> 1;
8888 -+ }
8889 -+
8890 -+ if ( vmul )
8891 -+ {
8892 -+ y_shift -= 64 * ( extra >> 1 );
8893 -+ height += 3 * extra;
8894 -+ y_top += extra >> 1;
8895 -+ }
8896 - }
8897 -+#endif
8898 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8899 - }
8900 -
8901 - #endif
8902 -@@ -239,6 +3475,9 @@
8903 - bitmap->pitch = pitch;
8904 -
8905 - /* translate outline to render it into the bitmap */
8906 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8907 -+ if (align_called == 0)
8908 -+#endif
8909 - FT_Outline_Translate( outline, -x_shift, -y_shift );
8910 -
8911 - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
8912 -@@ -288,9 +3527,107 @@
8913 - vec->y /= 3;
8914 - }
8915 -
8916 -+#ifdef FT_CONFIG_OPTION_INFINALITY_PATCHSET
8917 -+ if ( ppem <= MAX_PPEM && ppem >= MIN_PPEM )
8918 -+ {
8919 -+ if ( align_called == 0 && (alignment_strength > 0 || fitting_strength > 0))
8920 -+ _lcd_stem_align ( bitmap, mode, slot, &translate_value, &scale_value,
8921 -+ alignment_strength, fitting_strength, &embolden_value );
8922 -+
8923 -+ if ((translate_value != 0 || scale_value != 1.0) && align_called == 0)
8924 -+ {
8925 -+ align_called = 1;
8926 -+ goto RERENDER;
8927 -+ }
8928 -+
8929 -+ if ( mode == FT_RENDER_MODE_LCD )
8930 -+ {
8931 -+
8932 -+ if (fringe_filter_strength > 0 /*&& autohinted*/)
8933 -+ _ft_lcd_fringe_filter( bitmap, mode, fringe_filter_strength, slot->library );
8934 -+
8935 -+ /*if (autohinted)
8936 -+ _ft_lcd_stem_end_filter( bitmap, mode, 100, slot->library );*/
8937 -+
8938 -+ if ( gamma_correction_lt > 0 && gamma_correction_value != 1.0 )
8939 -+ _ft_lcd_gamma_correction_correction( bitmap, mode, slot, gamma_correction_lt, gamma_correction_value );
8940 -+
8941 -+ chromeos_cutoff = (FT_Byte)(0.5 * 255.0) * (chromeos_style_sharpening_strength / 100.0);
8942 -+ chromeos_gamma_value = 1;
8943 -+
8944 -+ if (chromeos_style_sharpening_strength > 0)
8945 -+ _ft_lcd_chromeos_sharpen( bitmap, mode, chromeos_cutoff, chromeos_gamma_value );
8946 -+
8947 -+ if (ppem > 8)
8948 -+ if (windows_style_sharpening_strength > 0)
8949 -+ _ft_lcd_windows_sharpen( bitmap, mode, windows_style_sharpening_strength, slot->library );
8950 -+
8951 -+ if (autohinted && (cur_width * 100) / 64 > autohint_horizontal_stem_darken_strength
8952 -+ && autohint_horizontal_stem_darken_strength != 0)
8953 -+ autohint_horizontal_stem_darken_strength = (cur_width * 100) / 64;
8954 -+
8955 -+ if (autohint_horizontal_stem_darken_strength > 100)
8956 -+ autohint_horizontal_stem_darken_strength = 100;
8957 -+
8958 -+ /* only do on autohinted fonts */
8959 -+ /* Necessary to do on some non-thin fonts, which is why it is outside */
8960 -+ /* of the below conditional */
8961 -+ if (autohint_horizontal_stem_darken_strength > 0 && autohinted )
8962 -+ _ft_lcd_darken_x ( bitmap, mode, autohint_horizontal_stem_darken_strength, slot->library );
8963 -+
8964 -+ /* Enhance thin fonts */
8965 -+ if (autohinted)
8966 -+ {
8967 -+ /* if forcibly set use that, otherwise make a good estimate */
8968 -+ if ( !_ft_bitmap_bc ( bitmap, (float)get_brightness(slot->face->family_name, ppem) / 300.0,
8969 -+ (float)get_contrast(slot->face->family_name, ppem) / 300.0))
8970 -+ {
8971 -+ FT_Bool is_fixed_name = FALSE;
8972 -+ if ( slot->face->family_name
8973 -+ && strcasestr(slot->face->family_name, "Mono") )
8974 -+ is_fixed_name = TRUE;
8975 -+
8976 -+ /* Darken vertical stems */
8977 -+ _ft_lcd_darken_y ( bitmap, mode, autohint_vertical_stem_darken_strength, slot->library);
8978 -+
8979 -+ /* Adjust brightness and contrast automatically based on stem width */
8980 -+ if (cur_width != 0 && cur_width < 30 ) cur_width = 30;
8981 -+ if (cur_width >= 30 && cur_width <= 60 )
8982 -+ {
8983 -+ float ppem_factor = sliding_scale ( 5, 11, 0.0, 1.0, ppem);
8984 -+ float brightness_factor = sliding_scale ( 30, 52, -.3, 0.0, cur_width);
8985 -+ float contrast_factor = sliding_scale ( 30, 52, .45, 0.0, cur_width);
8986 -+ _ft_bitmap_bc ( bitmap, ppem_factor * brightness_factor, ppem_factor * contrast_factor);
8987 -+
8988 -+ /* Only cap variable width thin-stemmed fonts */
8989 -+ if (!FT_IS_FIXED_WIDTH( slot->face ) && !is_fixed_name)
8990 -+ _ft_bitmap_cap ( bitmap, (cur_width * 150) / 64, slot->library );
8991 -+ }
8992 -+ }
8993 -+ }
8994 -+
8995 -+
8996 -+ if ( slot->library->lcd_filter_func )
8997 -+ slot->library->lcd_filter_func( bitmap, mode, slot->library );
8998 -+
8999 -+ if (grayscale_filter_strength > 0)
9000 -+ _ft_lcd_grayscale_filter( bitmap, mode, grayscale_filter_strength, slot->library );
9001 -+
9002 -+ }
9003 -+
9004 -+ /* Global values */
9005 -+ if (brightness_value != 0 || contrast_value != 0)
9006 -+ _ft_bitmap_bc ( bitmap, (float)brightness_value / 300.0, (float)contrast_value / 300.0);
9007 -+
9008 -+ FT_Outline_Done( slot->library, outline_orig );
9009 -+ }
9010 -+ else if ( mode == FT_RENDER_MODE_LCD && slot->library->lcd_filter_func )
9011 -+ slot->library->lcd_filter_func( bitmap, mode, slot->library );
9012 -+#else
9013 - if ( slot->library->lcd_filter_func )
9014 - slot->library->lcd_filter_func( bitmap, mode, slot->library );
9015 -
9016 -+#endif /* FT_CONFIG_OPTION_INFINALITY_PATCHSET */
9017 - #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
9018 -
9019 - /* render outline into bitmap */
9020
9021 diff --git a/media-libs/freetype/freetype-2.4.10-r1.ebuild b/media-libs/freetype/freetype-2.4.10-r1.ebuild
9022 deleted file mode 100644
9023 index e0bdde5..0000000
9024 --- a/media-libs/freetype/freetype-2.4.10-r1.ebuild
9025 +++ /dev/null
9026 @@ -1,142 +0,0 @@
9027 -# Copyright 1999-2012 Gentoo Foundation
9028 -# Distributed under the terms of the GNU General Public License v2
9029 -# $Header: $
9030 -
9031 -EAPI="4"
9032 -
9033 -inherit autotools eutils flag-o-matic libtool multilib
9034 -
9035 -DESCRIPTION="A high-quality and portable font engine"
9036 -HOMEPAGE="http://www.freetype.org/"
9037 -SRC_URI="mirror://sourceforge/freetype/${P/_/}.tar.bz2
9038 - utils? ( mirror://sourceforge/freetype/ft2demos-${PV}.tar.bz2 )
9039 - doc? ( mirror://sourceforge/freetype/${PN}-doc-${PV}.tar.bz2 )"
9040 -
9041 -LICENSE="FTL GPL-2"
9042 -SLOT="2"
9043 -KEYWORDS="~amd64 ~x86"
9044 -IUSE="X auto-hinter bindist bzip2 debug doc fontforge lcdfilter static-libs utils"
9045 -
9046 -DEPEND="sys-libs/zlib
9047 - bzip2? ( app-arch/bzip2 )
9048 - X? ( x11-libs/libX11
9049 - x11-libs/libXau
9050 - x11-libs/libXdmcp )"
9051 -
9052 -RDEPEND="${DEPEND}
9053 - lcdfilter? ( media-libs/fontconfig-infinality )"
9054 -
9055 -src_prepare() {
9056 - enable_option() {
9057 - sed -i -e "/#define $1/a #define $1" \
9058 - include/freetype/config/ftoption.h \
9059 - || die "unable to enable option $1"
9060 - }
9061 -
9062 - disable_option() {
9063 - sed -i -e "/#define $1/ { s:^:/*:; s:$:*/: }" \
9064 - include/freetype/config/ftoption.h \
9065 - || die "unable to disable option $1"
9066 - }
9067 -
9068 - if ! use bindist; then
9069 - # See http://freetype.org/patents.html
9070 - # ClearType is covered by several Microsoft patents in the US
9071 - enable_option FT_CONFIG_OPTION_SUBPIXEL_RENDERING
9072 - fi
9073 -
9074 - if use auto-hinter; then
9075 - disable_option TT_CONFIG_OPTION_BYTECODE_INTERPRETER
9076 - enable_option TT_CONFIG_OPTION_UNPATENTED_HINTING
9077 - fi
9078 -
9079 - if use debug; then
9080 - enable_option FT_DEBUG_LEVEL_TRACE
9081 - enable_option FT_DEBUG_MEMORY
9082 - fi
9083 -
9084 - disable_option FT_CONFIG_OPTION_OLD_INTERNALS
9085 -
9086 - if use lcdfilter; then
9087 - epatch "${FILESDIR}"/freetype-add-subpixel-hinting-infinality.patch
9088 - epatch "${FILESDIR}"/freetype-entire-infinality-patchset.patch
9089 -
9090 - enable_option FT_CONFIG_OPTION_SUBPIXEL_RENDERING
9091 - enable_option TT_CONFIG_OPTION_SUBPIXEL_HINTING
9092 - fi
9093 -
9094 - epatch "${FILESDIR}"/${PN}-2.3.2-enable-valid.patch
9095 -
9096 - if use utils; then
9097 - cd "${WORKDIR}/ft2demos-${PV}"
9098 - sed -i -e "s:\.\.\/freetype2$:../freetype-${PV}:" Makefile || die
9099 - # Disable tests needing X11 when USE="-X". (bug #177597)
9100 - if ! use X; then
9101 - sed -i -e "/EXES\ +=\ ftdiff/ s:^:#:" Makefile || die
9102 - fi
9103 - fi
9104 -
9105 - if use prefix; then
9106 - cd "${S}"/builds/unix
9107 - eautoreconf
9108 - else
9109 - elibtoolize
9110 - fi
9111 - epunt_cxx
9112 -}
9113 -
9114 -src_configure() {
9115 - append-flags -fno-strict-aliasing
9116 - type -P gmake &> /dev/null && export GNUMAKE=gmake
9117 -
9118 - # we need non-/bin/sh to run configure
9119 - [[ -n ${CONFIG_SHELL} ]] && \
9120 - sed -i -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" \
9121 - "${S}"/builds/unix/configure
9122 -
9123 - econf \
9124 - $(use_enable static-libs static) \
9125 - $(use_with bzip2)
9126 -}
9127 -
9128 -src_compile() {
9129 - emake
9130 -
9131 - if use utils; then
9132 - einfo "Building utils"
9133 - cd "${WORKDIR}/ft2demos-${PV}"
9134 - # fix for Prefix, bug #339334
9135 - emake X11_PATH="${EPREFIX}/usr/$(get_libdir)"
9136 - fi
9137 -}
9138 -
9139 -src_install() {
9140 - emake DESTDIR="${D}" install
9141 -
9142 - if use utils; then
9143 - einfo "Installing utils"
9144 - rm "${WORKDIR}"/ft2demos-${PV}/bin/README
9145 - for ft2demo in ../ft2demos-${PV}/bin/*; do
9146 - ./builds/unix/libtool --mode=install $(type -P install) -m 755 "$ft2demo" \
9147 - "${ED}"/usr/bin
9148 - done
9149 - fi
9150 -
9151 - if use fontforge; then
9152 - # Probably fontforge needs less but this way makes things simplier...
9153 - einfo "Installing internal headers required for fontforge"
9154 - find src/truetype include/freetype/internal -name '*.h' | \
9155 - while read header; do
9156 - mkdir -p "${ED}/usr/include/freetype2/internal4fontforge/$(dirname ${header})"
9157 - cp ${header} "${ED}/usr/include/freetype2/internal4fontforge/$(dirname ${header})"
9158 - done
9159 - fi
9160 -
9161 - prune_libtool_files
9162 -
9163 - dodoc ChangeLog README
9164 - dodoc docs/{CHANGES,CUSTOMIZE,DEBUG,*.txt,PROBLEMS,TODO}
9165 -
9166 - use doc && dohtml -r docs/*
9167 -
9168 -}