Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ TrueType information
TT_WEIGHT_CLASS
TT_FS_SELECTION

LCD Filtering
-------------

.. autosummary::
:toctree: _generated

set_lcd_filter
set_lcd_filter_weights

Basic Types
-----------

Expand Down
108 changes: 108 additions & 0 deletions docstrings/lcd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-

# Copyright (c) 2015, Michael Droettboom All rights reserved.

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:

# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# The views and conclusions contained in the software and
# documentation are those of the authors and should not be interpreted
# as representing official policies, either expressed or implied, of
# the FreeBSD Project.

from __future__ import print_function, unicode_literals, absolute_import

set_lcd_filter = """
Apply color filtering to LCD decimated bitmaps.

Works when called `Glyph.render` with `RENDER_MODE.LCD` or `RENDER_MODE.LCD_V`.

Parameters
----------

filter : `LCD_FILTER` constant

Notes
-----
This feature is always disabled by default. Clients must make an
explicit call to this function with a `filter` value other than
`LCD_FILTER.NONE` in order to enable it.

Due to PATENTS covering subpixel rendering, this function doesn't do
anything except raising `NotImplementedError` if the configuration
macro ``FT_CONFIG_OPTION_SUBPIXEL_RENDERING`` is not defined in your
build of the library, which should correspond to all default builds of
FreeType.
"""

set_lcd_filter_weights = """
Enable LCD filter with custom weights.

Parameters
----------
a, b, c, d, e : int
The filter weights

Notes
-----
Due to PATENTS covering subpixel rendering, this function doesn't do
anything except raising `NotImplementedError` if the configuration
macro ``FT_CONFIG_OPTION_SUBPIXEL_RENDERING`` is not defined in your
build of the library, which should correspond to all default builds of
FreeType.
"""


LCD_FILTER = """
Identifies various types of LCD filters.

- `NONE`: Do not perform filtering. When used with subpixel rendering,
this results in sometimes severe color fringes.

- `DEFAULT`: The default filter reduces color fringes considerably, at
the cost of a slight blurriness in the output. It is a beveled,
normalized, and color-balanced five-tap filter that is more
forgiving to screens with non-ideal gamma curves and viewing
angles. Note that while color-fringing is reduced, it can only be
minimized by using linear alpha blending and gamma correction to
render glyphs onto surfaces. The default filter weights are [0x08
0x4D 0x56 0x4D 0x08].

- `LIGHT`: The light filter is a variant that is sharper at the cost
of slightly more color fringes than the default one. It is a boxy,
normalized, and color-balanced three-tap filter that is less
forgiving to screens with non-ideal gamma curves and viewing
angles. This filter works best when the rendering system uses linear
alpha blending and gamma correction to render glyphs onto
surfaces. The light filter weights are [0x00 0x55 0x56 0x55 0x00].

- `LEGACY`: This filter corresponds to the original libXft color
filter. It provides high contrast output but can exhibit really bad
color fringes if glyphs are not extremely well hinted to the pixel
grid. In other words, it only works well if the TrueType bytecode
interpreter is enabled and high-quality hinted fonts are used.

This filter is only provided for comparison purposes, and might be
disabled or stay unsupported in the future.
"""
5 changes: 5 additions & 0 deletions examples/rendering_modes.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@ def rendering_modes(char):
if isinstance(char, bytes):
char = char.decode('utf-8')

try:
ft.set_lcd_filter(ft.LCD_FILTER.LIGHT)
except NotImplementedError:
print("LCD filtering is not available in your freetype build")

rendering_modes(char)
49 changes: 49 additions & 0 deletions src/freetypy.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ either expressed or implied, of the FreeBSD Project.
#include "glyph.h"
#include "glyph_metrics.h"
#include "layout.h"
#include "lcd.h"
#include "matrix.h"
#include "outline.h"
#include "sfntname.h"
Expand All @@ -58,6 +59,9 @@ either expressed or implied, of the FreeBSD Project.
#include "vector.h"
#include "version.h"

#include "doc/lcd.h"

#include "freetype/ftlcdfil.h"

static FT_Library ft_library;

Expand All @@ -66,7 +70,51 @@ FT_Library get_ft_library()
return ft_library;
}


PyObject *
py_set_lcd_filter(PyObject *self, PyObject *args, PyObject *kwargs)
{
int filter;

static char *kwlist[] = {"filter", NULL};

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_lcd_filter", kwlist,
&filter)) {
return NULL;
}

if (ftpy_exc(FT_Library_SetLcdFilter(get_ft_library(), filter))) {
return NULL;
}

Py_RETURN_NONE;
}


PyObject *
py_set_lcd_filter_weights(PyObject *self, PyObject *args, PyObject *kwargs)
{
char filters[5];

static char *kwlist[] = {"filter", NULL};

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "bbbbb:set_lcd_filter_weights", kwlist,
&filters[0], &filters[1], &filters[2],
&filters[3], &filters[4])) {
return NULL;
}

if (ftpy_exc(FT_Library_SetLcdFilterWeights(get_ft_library(), filters))) {
return NULL;
}

Py_RETURN_NONE;
}


static PyMethodDef module_methods[] = {
{"set_lcd_filter", (PyCFunction)py_set_lcd_filter, METH_VARARGS|METH_KEYWORDS, doc_set_lcd_filter},
{"set_lcd_filter_weights", (PyCFunction)py_set_lcd_filter_weights, METH_VARARGS|METH_KEYWORDS, doc_set_lcd_filter_weights},
{NULL} /* Sentinel */
};

Expand Down Expand Up @@ -147,6 +195,7 @@ PyObject *freetypy_module;
setup_Glyph(freetypy_module) ||
setup_Glyph_Metrics(freetypy_module) ||
setup_Layout(freetypy_module) ||
setup_Lcd(freetypy_module) ||
setup_Matrix(freetypy_module) ||
setup_Outline(freetypy_module) ||
setup_SfntName(freetypy_module) ||
Expand Down
53 changes: 53 additions & 0 deletions src/lcd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
Copyright (c) 2015, Michael Droettboom
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

#include "lcd.h"
#include "doc/lcd.h"

#include "freetype/ftlcdfil.h"

ftpy_ConstantType Py_FT_LCD_FILTER_ConstantType;
static PyTypeObject Py_FT_LCD_FILTER_Type;
#define LCD_FILTER_CONST(name) DEF_CONST(name, FT_LCD_FILTER)
static constant_def FT_LCD_FILTER_constants[] = {
LCD_FILTER_CONST(NONE),
LCD_FILTER_CONST(DEFAULT),
LCD_FILTER_CONST(LIGHT),
LCD_FILTER_CONST(LEGACY),
{NULL}
};


int setup_Lcd(PyObject *m)
{
define_constant_namespace(
m, &Py_FT_LCD_FILTER_Type, &Py_FT_LCD_FILTER_ConstantType,
"freetypy.LCD_FILTER",
doc_LCD_FILTER, FT_LCD_FILTER_constants);
}
38 changes: 38 additions & 0 deletions src/lcd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright (c) 2015, Michael Droettboom
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/

#ifndef __LCD_H__
#define __LCD_H__

#include "freetypy.h"
#include "constants.h"

int setup_Lcd(PyObject *m);

#endif /* __LCD_H__ */