Skip to content

Commit 0384771

Browse files
committed
Merge pull request #13 from mdboom/lcd
Lcd filters
2 parents e1c0d46 + 642d992 commit 0384771

File tree

6 files changed

+262
-0
lines changed

6 files changed

+262
-0
lines changed

doc/source/api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ TrueType information
134134
TT_WEIGHT_CLASS
135135
TT_FS_SELECTION
136136

137+
LCD Filtering
138+
-------------
139+
140+
.. autosummary::
141+
:toctree: _generated
142+
143+
set_lcd_filter
144+
set_lcd_filter_weights
145+
137146
Basic Types
138147
-----------
139148

docstrings/lcd.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright (c) 2015, Michael Droettboom All rights reserved.
4+
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions
7+
# are met:
8+
9+
# 1. Redistributions of source code must retain the above copyright
10+
# notice, this list of conditions and the following disclaimer.
11+
# 2. Redistributions in binary form must reproduce the above copyright
12+
# notice, this list of conditions and the following disclaimer in
13+
# the documentation and/or other materials provided with the
14+
# distribution.
15+
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25+
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26+
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
# POSSIBILITY OF SUCH DAMAGE.
28+
29+
# The views and conclusions contained in the software and
30+
# documentation are those of the authors and should not be interpreted
31+
# as representing official policies, either expressed or implied, of
32+
# the FreeBSD Project.
33+
34+
from __future__ import print_function, unicode_literals, absolute_import
35+
36+
set_lcd_filter = """
37+
Apply color filtering to LCD decimated bitmaps.
38+
39+
Works when called `Glyph.render` with `RENDER_MODE.LCD` or `RENDER_MODE.LCD_V`.
40+
41+
Parameters
42+
----------
43+
44+
filter : `LCD_FILTER` constant
45+
46+
Notes
47+
-----
48+
This feature is always disabled by default. Clients must make an
49+
explicit call to this function with a `filter` value other than
50+
`LCD_FILTER.NONE` in order to enable it.
51+
52+
Due to PATENTS covering subpixel rendering, this function doesn't do
53+
anything except raising `NotImplementedError` if the configuration
54+
macro ``FT_CONFIG_OPTION_SUBPIXEL_RENDERING`` is not defined in your
55+
build of the library, which should correspond to all default builds of
56+
FreeType.
57+
"""
58+
59+
set_lcd_filter_weights = """
60+
Enable LCD filter with custom weights.
61+
62+
Parameters
63+
----------
64+
a, b, c, d, e : int
65+
The filter weights
66+
67+
Notes
68+
-----
69+
Due to PATENTS covering subpixel rendering, this function doesn't do
70+
anything except raising `NotImplementedError` if the configuration
71+
macro ``FT_CONFIG_OPTION_SUBPIXEL_RENDERING`` is not defined in your
72+
build of the library, which should correspond to all default builds of
73+
FreeType.
74+
"""
75+
76+
77+
LCD_FILTER = """
78+
Identifies various types of LCD filters.
79+
80+
- `NONE`: Do not perform filtering. When used with subpixel rendering,
81+
this results in sometimes severe color fringes.
82+
83+
- `DEFAULT`: The default filter reduces color fringes considerably, at
84+
the cost of a slight blurriness in the output. It is a beveled,
85+
normalized, and color-balanced five-tap filter that is more
86+
forgiving to screens with non-ideal gamma curves and viewing
87+
angles. Note that while color-fringing is reduced, it can only be
88+
minimized by using linear alpha blending and gamma correction to
89+
render glyphs onto surfaces. The default filter weights are [0x08
90+
0x4D 0x56 0x4D 0x08].
91+
92+
- `LIGHT`: The light filter is a variant that is sharper at the cost
93+
of slightly more color fringes than the default one. It is a boxy,
94+
normalized, and color-balanced three-tap filter that is less
95+
forgiving to screens with non-ideal gamma curves and viewing
96+
angles. This filter works best when the rendering system uses linear
97+
alpha blending and gamma correction to render glyphs onto
98+
surfaces. The light filter weights are [0x00 0x55 0x56 0x55 0x00].
99+
100+
- `LEGACY`: This filter corresponds to the original libXft color
101+
filter. It provides high contrast output but can exhibit really bad
102+
color fringes if glyphs are not extremely well hinted to the pixel
103+
grid. In other words, it only works well if the TrueType bytecode
104+
interpreter is enabled and high-quality hinted fonts are used.
105+
106+
This filter is only provided for comparison purposes, and might be
107+
disabled or stay unsupported in the future.
108+
"""

examples/rendering_modes.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,9 @@ def rendering_modes(char):
9191
if isinstance(char, bytes):
9292
char = char.decode('utf-8')
9393

94+
try:
95+
ft.set_lcd_filter(ft.LCD_FILTER.LIGHT)
96+
except NotImplementedError:
97+
print("LCD filtering is not available in your freetype build")
98+
9499
rendering_modes(char)

src/freetypy.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ either expressed or implied, of the FreeBSD Project.
4040
#include "glyph.h"
4141
#include "glyph_metrics.h"
4242
#include "layout.h"
43+
#include "lcd.h"
4344
#include "matrix.h"
4445
#include "outline.h"
4546
#include "sfntname.h"
@@ -58,6 +59,9 @@ either expressed or implied, of the FreeBSD Project.
5859
#include "vector.h"
5960
#include "version.h"
6061

62+
#include "doc/lcd.h"
63+
64+
#include "freetype/ftlcdfil.h"
6165

6266
static FT_Library ft_library;
6367

@@ -66,7 +70,51 @@ FT_Library get_ft_library()
6670
return ft_library;
6771
}
6872

73+
74+
PyObject *
75+
py_set_lcd_filter(PyObject *self, PyObject *args, PyObject *kwargs)
76+
{
77+
int filter;
78+
79+
static char *kwlist[] = {"filter", NULL};
80+
81+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_lcd_filter", kwlist,
82+
&filter)) {
83+
return NULL;
84+
}
85+
86+
if (ftpy_exc(FT_Library_SetLcdFilter(get_ft_library(), filter))) {
87+
return NULL;
88+
}
89+
90+
Py_RETURN_NONE;
91+
}
92+
93+
94+
PyObject *
95+
py_set_lcd_filter_weights(PyObject *self, PyObject *args, PyObject *kwargs)
96+
{
97+
char filters[5];
98+
99+
static char *kwlist[] = {"filter", NULL};
100+
101+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "bbbbb:set_lcd_filter_weights", kwlist,
102+
&filters[0], &filters[1], &filters[2],
103+
&filters[3], &filters[4])) {
104+
return NULL;
105+
}
106+
107+
if (ftpy_exc(FT_Library_SetLcdFilterWeights(get_ft_library(), filters))) {
108+
return NULL;
109+
}
110+
111+
Py_RETURN_NONE;
112+
}
113+
114+
69115
static PyMethodDef module_methods[] = {
116+
{"set_lcd_filter", (PyCFunction)py_set_lcd_filter, METH_VARARGS|METH_KEYWORDS, doc_set_lcd_filter},
117+
{"set_lcd_filter_weights", (PyCFunction)py_set_lcd_filter_weights, METH_VARARGS|METH_KEYWORDS, doc_set_lcd_filter_weights},
70118
{NULL} /* Sentinel */
71119
};
72120

@@ -147,6 +195,7 @@ PyObject *freetypy_module;
147195
setup_Glyph(freetypy_module) ||
148196
setup_Glyph_Metrics(freetypy_module) ||
149197
setup_Layout(freetypy_module) ||
198+
setup_Lcd(freetypy_module) ||
150199
setup_Matrix(freetypy_module) ||
151200
setup_Outline(freetypy_module) ||
152201
setup_SfntName(freetypy_module) ||

src/lcd.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
Copyright (c) 2015, Michael Droettboom
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
The views and conclusions contained in the software and documentation are those
26+
of the authors and should not be interpreted as representing official policies,
27+
either expressed or implied, of the FreeBSD Project.
28+
*/
29+
30+
#include "lcd.h"
31+
#include "doc/lcd.h"
32+
33+
#include "freetype/ftlcdfil.h"
34+
35+
ftpy_ConstantType Py_FT_LCD_FILTER_ConstantType;
36+
static PyTypeObject Py_FT_LCD_FILTER_Type;
37+
#define LCD_FILTER_CONST(name) DEF_CONST(name, FT_LCD_FILTER)
38+
static constant_def FT_LCD_FILTER_constants[] = {
39+
LCD_FILTER_CONST(NONE),
40+
LCD_FILTER_CONST(DEFAULT),
41+
LCD_FILTER_CONST(LIGHT),
42+
LCD_FILTER_CONST(LEGACY),
43+
{NULL}
44+
};
45+
46+
47+
int setup_Lcd(PyObject *m)
48+
{
49+
define_constant_namespace(
50+
m, &Py_FT_LCD_FILTER_Type, &Py_FT_LCD_FILTER_ConstantType,
51+
"freetypy.LCD_FILTER",
52+
doc_LCD_FILTER, FT_LCD_FILTER_constants);
53+
}

src/lcd.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Copyright (c) 2015, Michael Droettboom
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
2. Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
25+
The views and conclusions contained in the software and documentation are those
26+
of the authors and should not be interpreted as representing official policies,
27+
either expressed or implied, of the FreeBSD Project.
28+
*/
29+
30+
#ifndef __LCD_H__
31+
#define __LCD_H__
32+
33+
#include "freetypy.h"
34+
#include "constants.h"
35+
36+
int setup_Lcd(PyObject *m);
37+
38+
#endif /* __LCD_H__ */

0 commit comments

Comments
 (0)