diff --git a/matrix.c b/matrix.c index 937fc136..94477cc8 100644 --- a/matrix.c +++ b/matrix.c @@ -1,4 +1,5 @@ // 11 october 2015 +#include #include "ui.h" #include "uipriv.h" @@ -14,20 +15,19 @@ void setIdentity(uiDrawMatrix *m) // TODO don't default to fallback functions within the fallback functions -// technique from "Programming with Quartz: 2D and PDF Graphics in Mac OS X" +// see https://msdn.microsoft.com/en-us/library/windows/desktop/ff684171%28v=vs.85%29.aspx#skew_transform // TODO if Windows 7 is ever dropped change this so we can pass in D2D1Tan() void fallbackSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount) { - uiDrawMatrix t, n; + uiDrawMatrix n; - setIdentity(&t); - fallbackTranslate(&t, x, y); setIdentity(&n); - n.M12 = tan(xamount); - n.M21 = tan(yamount); - fallbackMultiply(&n, &t); - // TODO undo the translation? - fallbackMultiply(&m, &n); + // TODO explain this + n.M12 = tan(yamount); + n.M21 = tan(xamount); + n.M31 = -y * tan(xamount); + n.M32 = -x * tan(yamount); + fallbackMultiply(m, &n); } // see windows/draw.c for more information diff --git a/test/drawtests.c b/test/drawtests.c index fd9f1ff1..f601a24b 100644 --- a/test/drawtests.c +++ b/test/drawtests.c @@ -900,12 +900,185 @@ static void drawD2DScale(uiAreaDrawParams *p) uiDrawFreePath(path); } -// TODO skewing https://msdn.microsoft.com/en-us/library/windows/desktop/dd756689%28v=vs.85%29.aspx -// especially TODO counterclockwise?! +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756689%28v=vs.85%29.aspx +// TODO counterclockwise?! +void drawD2DSkew(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; -// TODO translating https://msdn.microsoft.com/en-us/library/windows/desktop/dd756691%28v=vs.85%29.aspx + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 126.0, 301.5, 186.0 - 126.0, 361.5 - 301.5); + uiDrawPathEnd(path); -// TODO multiple transforms https://msdn.microsoft.com/en-us/library/windows/desktop/dd756672%28v=vs.85%29.aspx + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + // save for when we do the translated one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixSkew(&m, + 126.0, 301.5, + 45.0 * (M_PI / 180), 0); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + + // for testing purposes, show what happens if we skew about (0, 0) + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 0, -200); + uiDrawTransform(p->Context, &m); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixSkew(&m, + 0, 0, + 45.0 * (M_PI / 180), 0); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756691%28v=vs.85%29.aspx +static void drawD2DTranslate(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 126.0, 80.5, 186.0 - 126.0, 140.5 - 80.5); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 20, 10); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756672%28v=vs.85%29.aspx +// TODO the points seem off +static void drawD2DMultiTransforms(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix mtranslate; + uiDrawMatrix mrotate; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 300.0, 40.0, 360.0 - 300.0, 100.0 - 40.0); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawMatrixSetIdentity(&mtranslate); + uiDrawMatrixTranslate(&mtranslate, 20.0, 10.0); + uiDrawMatrixSetIdentity(&mrotate); + uiDrawMatrixRotate(&mrotate, + 330.0, 70.0, + 45.0 * (M_PI / 180)); + + // save for when we do the opposite one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawTransform(p->Context, &mrotate); + uiDrawTransform(p->Context, &mtranslate); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 40.0, 40.0, 100.0 - 40.0, 100.0 - 40.0); + uiDrawPathEnd(path); + + uiDrawMatrixSetIdentity(&mtranslate); + uiDrawMatrixTranslate(&mtranslate, 20.0, 10.0); + uiDrawMatrixSetIdentity(&mrotate); + uiDrawMatrixRotate(&mrotate, + 70.0, 70.0, + 45.0 * (M_PI / 180)); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawTransform(p->Context, &mtranslate); + uiDrawTransform(p->Context, &mrotate); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} // TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756675%28v=vs.85%29.aspx @@ -1593,6 +1766,9 @@ static const struct drawtest tests[] = { { "Direct2D: How to Create Geometry Groups", drawD2DGeometryGroup }, { "Direct2D: How to Rotate an Object", drawD2DRotate }, { "Direct2D: How to Scale an Object", drawD2DScale }, + { "Direct2D: How to Skew an Object", drawD2DSkew }, + { "Direct2D: How to Translate an Object", drawD2DTranslate }, + { "Direct2D: How to Apply Multiple Transforms to an Object", drawD2DMultiTransforms }, { "Direct2D: How to Draw and Fill a Complex Shape", drawD2DComplexShape }, { "cairo samples: arc", drawCSArc }, { "cairo samples: arc negative", drawCSArcNegative }, diff --git a/unix/GNUmakeinc.mk b/unix/GNUmakeinc.mk index 17a98754..1307550a 100644 --- a/unix/GNUmakeinc.mk +++ b/unix/GNUmakeinc.mk @@ -40,7 +40,7 @@ osCFLAGS = \ osLDFLAGS = \ -fvisibility=hidden \ -fPIC \ - `pkg-config --libs gtk+-3.0` + `pkg-config --libs gtk+-3.0` -lm osLDWarnUndefinedFlags = -Wl,--no-undefined -Wl,--no-allow-shlib-undefined diff --git a/unix/draw.c b/unix/draw.c index 565a0edc..875b78bc 100644 --- a/unix/draw.c +++ b/unix/draw.c @@ -358,6 +358,7 @@ void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount) m2c(m, &c); cairo_matrix_translate(&c, x, y); cairo_matrix_rotate(&c, amount); + // TODO undo the translation? also cocoa backend cairo_matrix_translate(&c, -x, -y); c2m(&c, m); }