Skip to content

Commit

Permalink
Move the pressurecurve calculation into a separate file
Browse files Browse the repository at this point in the history
There's nothing driver-specific about this and it allows us to test it
separately or write tools to test it.
  • Loading branch information
whot committed Nov 14, 2023
1 parent 55a10e3 commit 81d24e2
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 133 deletions.
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ src_wacom_core = [
'src/wcmConfig.c',
'src/wcmFilter.c',
'src/wcmFilter.h',
'src/wcmPressureCurve.c',
'src/wcmTouchFilter.c',
'src/wcmTouchFilter.h',
'src/wcmUSB.c',
Expand Down
2 changes: 2 additions & 0 deletions src/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ DRIVER_SOURCES= \
$(top_srcdir)/src/wcmConfig.c \
$(top_srcdir)/src/wcmFilter.c \
$(top_srcdir)/src/wcmFilter.h \
$(top_srcdir)/src/wcmPressureCurve.c \
$(top_srcdir)/src/wcmPressureCurve.h \
$(top_srcdir)/src/xf86WacomDefs.h \
$(top_srcdir)/src/wcmUSB.c \
$(top_srcdir)/src/wcmValidateDevice.c \
Expand Down
134 changes: 1 addition & 133 deletions src/wcmFilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,7 @@
#include <math.h>
#include "xf86Wacom.h"
#include "wcmFilter.h"

/*****************************************************************************
* Static functions
****************************************************************************/

static void filterCurveToLine(int* pCurve, int nMax, double x0, double y0,
double x1, double y1, double x2, double y2,
double x3, double y3);
static int filterOnLine(double x0, double y0, double x1, double y1,
double a, double b);
static void filterLine(int* pCurve, int nMax, int x0, int y0, int x1, int y1);
#include "wcmPressureCurve.h"


/*****************************************************************************
Expand Down Expand Up @@ -101,128 +91,6 @@ void wcmResetSampleCounter(const WacomChannelPtr pChannel)
}


static void filterNearestPoint(double x0, double y0, double x1, double y1,
double a, double b, double* x, double* y)
{
double vx, vy, wx, wy, d1, d2, c;

wx = a - x0; wy = b - y0;
vx = x1 - x0; vy = y1 - y0;

d1 = vx * wx + vy * wy;
if (d1 <= 0)
{
*x = x0;
*y = y0;
}
else
{
d2 = vx * vx + vy * vy;
if (d1 >= d2)
{
*x = x1;
*y = y1;
}
else
{
c = d1 / d2;
*x = x0 + c * vx;
*y = y0 + c * vy;
}
}
}

static int filterOnLine(double x0, double y0, double x1, double y1,
double a, double b)
{
double x, y, d;
filterNearestPoint(x0,y0,x1,y1,a,b,&x,&y);
d = (x-a)*(x-a) + (y-b)*(y-b);
return d < 0.00001; /* within 100th of a point (1E-2 squared) */
}

static void filterCurveToLine(int* pCurve, int nMax, double x0, double y0,
double x1, double y1, double x2, double y2,
double x3, double y3)
{
double x01,y01,x32,y32,xm,ym;
double c1,d1,c2,d2,e,f;

/* check if control points are on line */
if (filterOnLine(x0,y0,x3,y3,x1,y1) && filterOnLine(x0,y0,x3,y3,x2,y2))
{
filterLine(pCurve,nMax,
(int)(x0*nMax),(int)(y0*nMax),
(int)(x3*nMax),(int)(y3*nMax));
return;
}

/* calculate midpoints */
x01 = (x0 + x1) / 2; y01 = (y0 + y1) / 2;
x32 = (x3 + x2) / 2; y32 = (y3 + y2) / 2;

/* calc split point */
xm = (x1 + x2) / 2; ym = (y1 + y2) / 2;

/* calc control points and midpoint */
c1 = (x01 + xm) / 2; d1 = (y01 + ym) / 2;
c2 = (x32 + xm) / 2; d2 = (y32 + ym) / 2;
e = (c1 + c2) / 2; f = (d1 + d2) / 2;

/* do each side */
filterCurveToLine(pCurve,nMax,x0,y0,x01,y01,c1,d1,e,f);
filterCurveToLine(pCurve,nMax,e,f,c2,d2,x32,y32,x3,y3);
}

static void filterLine(int* pCurve, int nMax, int x0, int y0, int x1, int y1)
{
int dx, dy, ax, ay, sx, sy, x, y, d;

/* sanity check */
if ((x0 < 0) || (y0 < 0) || (x1 < 0) || (y1 < 0) ||
(x0 > nMax) || (y0 > nMax) || (x1 > nMax) || (y1 > nMax))
return;

dx = x1 - x0; ax = abs(dx) * 2; sx = (dx>0) ? 1 : -1;
dy = y1 - y0; ay = abs(dy) * 2; sy = (dy>0) ? 1 : -1;
x = x0; y = y0;

/* x dominant */
if (ax > ay)
{
d = ay - ax / 2;
while (1)
{
pCurve[x] = y;
if (x == x1) break;
if (d >= 0)
{
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
}

/* y dominant */
else
{
d = ax - ay / 2;
while (1)
{
pCurve[x] = y;
if (y == y1) break;
if (d >= 0)
{
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
}
}
static void storeRawSample(WacomCommonPtr common, WacomChannelPtr pChannel,
WacomDeviceStatePtr ds)
{
Expand Down
156 changes: 156 additions & 0 deletions src/wcmPressureCurve.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright 1995-2002 by Frederic Lepied, France. <Lepied@XFree86.org>
* Copyright 2002-2008 by Ping Cheng, Wacom. <pingc@wacom.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <config.h>

#include "wcmPressureCurve.h"

#include <math.h>
#include <stdlib.h>

static int filterOnLine(double x0, double y0, double x1, double y1,
double a, double b);
static void filterLine(int* pCurve, int nMax, int x0, int y0, int x1, int y1);


static void filterNearestPoint(double x0, double y0, double x1, double y1,
double a, double b, double* x, double* y)
{
double vx, vy, wx, wy, d1, d2, c;

wx = a - x0; wy = b - y0;
vx = x1 - x0; vy = y1 - y0;

d1 = vx * wx + vy * wy;
if (d1 <= 0)
{
*x = x0;
*y = y0;
}
else
{
d2 = vx * vx + vy * vy;
if (d1 >= d2)
{
*x = x1;
*y = y1;
}
else
{
c = d1 / d2;
*x = x0 + c * vx;
*y = y0 + c * vy;
}
}
}

static int filterOnLine(double x0, double y0, double x1, double y1,
double a, double b)
{
double x, y, d;
filterNearestPoint(x0,y0,x1,y1,a,b,&x,&y);
d = (x-a)*(x-a) + (y-b)*(y-b);
return d < 0.00001; /* within 100th of a point (1E-2 squared) */
}

void filterCurveToLine(int* pCurve, int nMax, double x0, double y0,
double x1, double y1, double x2, double y2,
double x3, double y3)
{
double x01,y01,x32,y32,xm,ym;
double c1,d1,c2,d2,e,f;

/* check if control points are on line */
if (filterOnLine(x0,y0,x3,y3,x1,y1) && filterOnLine(x0,y0,x3,y3,x2,y2))
{
filterLine(pCurve,nMax,
(int)(x0*nMax),(int)(y0*nMax),
(int)(x3*nMax),(int)(y3*nMax));
return;
}

/* calculate midpoints */
x01 = (x0 + x1) / 2; y01 = (y0 + y1) / 2;
x32 = (x3 + x2) / 2; y32 = (y3 + y2) / 2;

/* calc split point */
xm = (x1 + x2) / 2; ym = (y1 + y2) / 2;

/* calc control points and midpoint */
c1 = (x01 + xm) / 2; d1 = (y01 + ym) / 2;
c2 = (x32 + xm) / 2; d2 = (y32 + ym) / 2;
e = (c1 + c2) / 2; f = (d1 + d2) / 2;

/* do each side */
filterCurveToLine(pCurve,nMax,x0,y0,x01,y01,c1,d1,e,f);
filterCurveToLine(pCurve,nMax,e,f,c2,d2,x32,y32,x3,y3);
}

static void filterLine(int* pCurve, int nMax, int x0, int y0, int x1, int y1)
{
int dx, dy, ax, ay, sx, sy, x, y, d;

/* sanity check */
if ((x0 < 0) || (y0 < 0) || (x1 < 0) || (y1 < 0) ||
(x0 > nMax) || (y0 > nMax) || (x1 > nMax) || (y1 > nMax))
return;

dx = x1 - x0; ax = abs(dx) * 2; sx = (dx>0) ? 1 : -1;
dy = y1 - y0; ay = abs(dy) * 2; sy = (dy>0) ? 1 : -1;
x = x0; y = y0;

/* x dominant */
if (ax > ay)
{
d = ay - ax / 2;
while (1)
{
pCurve[x] = y;
if (x == x1) break;
if (d >= 0)
{
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
}

/* y dominant */
else
{
d = ax - ay / 2;
while (1)
{
pCurve[x] = y;
if (y == y1) break;
if (d >= 0)
{
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
}
}

/* vim: set noexpandtab tabstop=8 shiftwidth=8: */

24 changes: 24 additions & 0 deletions src/wcmPressureCurve.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 1995-2002 by Frederic Lepied, France. <Lepied@XFree86.org>
* Copyright 2002-2008 by Ping Cheng, Wacom. <pingc@wacom.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <config.h>

void filterCurveToLine(int* pCurve, int nMax, double x0, double y0,
double x1, double y1, double x2, double y2,
double x3, double y3);

0 comments on commit 81d24e2

Please sign in to comment.