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); }
/***************************************************************************** * wcmSetPressureCurve -- apply user-defined curve to pressure values ****************************************************************************/ void wcmSetPressureCurve(WacomDevicePtr pDev, int x0, int y0, int x1, int y1) { int i; /* sanity check values */ if (!wcmCheckPressureCurveValues(x0, y0, x1, y1)) return; /* linear by default */ for (i=0; i<=FILTER_PRESSURE_RES; ++i) pDev->pPressCurve[i] = i; /* draw bezier line from bottom-left to top-right using ctrl points */ filterCurveToLine(pDev->pPressCurve, FILTER_PRESSURE_RES, 0.0, 0.0, /* bottom left */ x0/100.0, y0/100.0, /* control point 1 */ x1/100.0, y1/100.0, /* control point 2 */ 1.0, 1.0); /* top right */ pDev->nPressCtrl[0] = x0; pDev->nPressCtrl[1] = y0; pDev->nPressCtrl[2] = x1; pDev->nPressCtrl[3] = y1; }
/***************************************************************************** * wcmSetPressureCurve -- apply user-defined curve to pressure values ****************************************************************************/ void wcmSetPressureCurve(WacomDevicePtr pDev, int x0, int y0, int x1, int y1) { /* sanity check values */ if (!wcmCheckPressureCurveValues(x0, y0, x1, y1)) return; /* A NULL pPressCurve indicates the (default) linear curve */ if (x0 == 0 && y0 == 0 && x1 == 100 && y1 == 100) { free(pDev->pPressCurve); pDev->pPressCurve = NULL; } else if (!pDev->pPressCurve) { pDev->pPressCurve = calloc(FILTER_PRESSURE_RES+1, sizeof(*pDev->pPressCurve)); if (!pDev->pPressCurve) { LogMessageVerbSigSafe(X_WARNING, 0, "Unable to allocate memory for pressure curve; using default.\n"); x0 = 0; y0 = 0; x1 = 100; y1 = 100; } } if (pDev->pPressCurve) filterCurveToLine(pDev->pPressCurve, FILTER_PRESSURE_RES, 0.0, 0.0, /* bottom left */ x0/100.0, y0/100.0, /* control point 1 */ x1/100.0, y1/100.0, /* control point 2 */ 1.0, 1.0); /* top right */ pDev->nPressCtrl[0] = x0; pDev->nPressCtrl[1] = y0; pDev->nPressCtrl[2] = x1; pDev->nPressCtrl[3] = y1; }