From c93a16eca394caf213143441502f38b40e8517eb Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Mon, 8 Aug 2011 09:24:28 +1000 Subject: [PATCH] Linear, Conical and Radial gradients --- lib/x11/xcore.js | 4 +- test/render-simplest.pl | 6 +- test/render.js | 143 +++++++++++++++++++++++++++++++++++----- 3 files changed, 130 insertions(+), 23 deletions(-) diff --git a/lib/x11/xcore.js b/lib/x11/xcore.js index a5ab567..d79b322 100644 --- a/lib/x11/xcore.js +++ b/lib/x11/xcore.js @@ -45,13 +45,13 @@ function XClient(stream, displayNum, screenNum) pack_stream.on('data', function( data ) { //console.error(hexy(data, {prefix: 'from packer '})); for (var i=0; i < data.length; ++i) - console.error('<<< ' + data[i]); + console.log('<<< ' + data[i]); stream.write(data); }); stream.on('data', function( data ) { //console.error(hexy(data, {prefix: 'to unpacker '})); for (var i=0; i < data.length; ++i) - console.error('>>> ' + data[i]); + console.log('>>> ' + data[i]); pack_stream.write(data); }); diff --git a/test/render-simplest.pl b/test/render-simplest.pl index 666145e..85f3c95 100644 --- a/test/render-simplest.pl +++ b/test/render-simplest.pl @@ -18,12 +18,12 @@ $X->CreateWindow($win, $X->root, 'InputOutput', $X->root_depth, $X->MapWindow($win); my $picture = $X->new_rsrc; -$X->RenderCreatePicture($picture, $win, $rgb24);#, 'poly_edge' => 'Smooth', 'poly_mode' => 'Precise'); +$X->RenderCreatePicture($picture, $win, $rgb24, 'poly_edge' => 'Smooth', 'poly_mode' => 'Precise'); my $pixmap = $X->new_rsrc; $X->CreatePixmap($pixmap, $win, 32, 1000, 1000); my $pix_pict = $X->new_rsrc; -$X->RenderCreatePicture($pix_pict, $pixmap, $rgba32);#, 'poly_edge' => 'Smooth', 'poly_mode' => 'Precise'); +$X->RenderCreatePicture($pix_pict, $pixmap, $rgba32, 'poly_edge' => 'Smooth', 'poly_mode' => 'Precise'); $X->RenderFillRectangles('Src', $pix_pict, [0xffff, 0, 0, 0x8000], [0, 0, 1000, 1000]); $X->event_handler('queue'); @@ -31,7 +31,7 @@ $X->event_handler('queue'); sub draw { $X->RenderFillRectangles('Src', $picture, [(0xffff)x4], [0, 0, 500, 500]); - $X->RenderTriangles('Over', $pix_pict, 500, 500, $picture, 0, [(250, 100), (100, 350), (400, 350)]); + $X->RenderTriangles('Over', $pix_pict, 500, 500, $picture, 0, [(250, 100), (100, 350), (400, 350), (175, 100), (185, 100), (180, 0)]); #$X->RenderFillRectangles('Src', $picture, [(0xffff, 0, 0, 0xffff)], [10, 10, 50, 50]); } diff --git a/test/render.js b/test/render.js index 6f94804..c2080cd 100644 --- a/test/render.js +++ b/test/render.js @@ -7,7 +7,8 @@ var x11 = require('../lib/x11'); x11.createClient( function(display) { var X = display.client; - X.QueryExtension('RENDER', function(ext) { + X.QueryExtension('RENDER', function(ext) { + function RenderQueryVersion(clientMaj, clientMin, callback) { X.seq_num++; @@ -76,6 +77,8 @@ x11.createClient( ['alphaMap', 'L'], ['alphaXOrigin', 's'], ['alphaYOrigin', 's'], + ['clipXOrigin', 's'], + ['clipYOrigin', 's'], ['clipMask', 'L'], ['graphicsExposures', 'C'], ['subwindowMode', 'C'], @@ -123,7 +126,6 @@ x11.createClient( params[2] = reqLen; params[6] = mask; } - console.log([format, params]); X.pack_stream.pack(format, params); X.pack_stream.flush(); } @@ -133,6 +135,42 @@ x11.createClient( return parseInt(f*65536); } + function RenderRadialGradient(pid, p1, p2, r1, r2, stops) + { + // TODO: merge with linear gradient + X.seq_num++; + var reqLen = 9+stops.length*3; //header + params + 1xStopfix+2xColors + var format = 'CCSLLLLLLLL'; + var params = [ext.majorOpcode, 35, reqLen, pid]; + params.push(floatToFix(p1[0])); // L + params.push(floatToFix(p1[1])); + params.push(floatToFix(p2[0])); + params.push(floatToFix(p2[1])); // L + params.push(floatToFix(r1)); // L + params.push(floatToFix(r2)); // L + + params.push(stops.length); + + // [ [float stopDist, [float r, g, b, a] ], ...] + // stop distances + for (var i=0; i < stops.length; ++i) + { + format += 'L'; + // TODO: we know total params length in advance. ? params[index] = + params.push(floatToFix(stops[i][0])) + } + // colors + for (var i=0; i < stops.length; ++i) + { + format += 'SSSS'; + for (var j=0; j < 4; ++j) + params.push(stops[i][1][j]); + } + console.log([format, params]); + X.pack_stream.pack(format, params); + X.pack_stream.flush(); + } + function RenderLinearGradient(pid, p1, p2, stops) { X.seq_num++; @@ -166,6 +204,37 @@ x11.createClient( X.pack_stream.flush(); } + function RenderConicalGradient(pid, center, angle, stops) + { + X.seq_num++; + var reqLen = 6+stops.length*3; //header + params + 1xStopfix+2xColors + var format = 'CCSLLLLL'; + var params = [ext.majorOpcode, 36, reqLen, pid]; + params.push(floatToFix(center[0])); // L + params.push(floatToFix(center[1])); + params.push(floatToFix(angle)); // L + + params.push(stops.length); + + // [ [float stopDist, [float r, g, b, a] ], ...] + // stop distances + for (var i=0; i < stops.length; ++i) + { + format += 'L'; + // TODO: we know total params length in advance. ? params[index] = + params.push(floatToFix(stops[i][0])) + } + // colors + for (var i=0; i < stops.length; ++i) + { + format += 'SSSS'; + for (var j=0; j < 4; ++j) + params.push(stops[i][1][j]); + } + console.log([format, params]); + X.pack_stream.pack(format, params); + } + function RenderFillRectangles(op, pid, color, rects) { X.seq_num++; @@ -197,16 +266,30 @@ x11.createClient( .flush(); } + function RenderTrapezoids(op, src, srcX, srcY, dst, maskFormat, trapz) + { + X.seq_num++; + var format = 'CCSCxxxLLLss'; + var params = [ext.majorOpcode, 10, 6+trapz.length, op, src, dst, maskFormat, srcX, srcY]; + for (var i=0; i < trapz.length; i+=8) + { + format += 'llllllll'; + for (var j=0; j < 8; ++j) + params.push(floatToFix(trapz[i*8 + j])); + } + console.log([format, params]); + X.pack_stream.pack(format, params); + X.pack_stream.flush(); + } + function RenderTriangles(op, src, srcX, srcY, dst, maskFormat, tris) { X.seq_num++; var format = 'CCSCxxxLLLss'; - //var format = 'CCSCxxxLLLSS'; var params = [ext.majorOpcode, 11, 6+tris.length, op, src, dst, maskFormat, srcX, srcY]; for (var i=0; i < tris.length; i+=6) { format += 'llllll'; - //format += 'LLLLLL'; //TODO: Array.copy params.push(floatToFix(tris[i*6 + 0])); // x1 params.push(floatToFix(tris[i*6 + 1])); // y1 @@ -215,7 +298,6 @@ x11.createClient( params.push(floatToFix(tris[i*6 + 4])); // x3 params.push(floatToFix(tris[i*6 + 5])); // y3 } - console.log([format, params]); X.pack_stream.pack(format, params); X.pack_stream.flush(); } @@ -224,27 +306,52 @@ x11.createClient( var win = X.AllocID(); var white = display.screen[0].white_pixel; var black = display.screen[0].black_pixel; - X.CreateWindow(win, root, 0, 0, 300, 300, 4, 1, 0, { backgroundPixel: white, eventMask: x11.eventMask.Exposure }); + X.CreateWindow(win, root, 0, 0, 500, 500, 4, 1, 0, { backgroundPixel: white, eventMask: x11.eventMask.Exposure }); X.MapWindow(win); + + //rgb24: 42 32: 38 rd: 24 var picture = X.AllocID(); - RenderCreatePicture(picture, win, 71); //, { polyEdge: 1, polyMode: 0 } ); - var pixmap = X.AllocID(); - X.CreatePixmap(pixmap, win, 32, 1000, 1000); - var pix_pict = X.AllocID(); - console.log(['!!!!!!!!!!!!!!!', picture, pixmap, pix_pict]); - RenderCreatePicture(pix_pict, pixmap, 69); //, { polyEdge: 1, polyMode: 0 }); - RenderFillRectangles(1, pix_pict, [0xffff, 0, 0, 0x8000], [0, 0, 1000, 1000]); + RenderCreatePicture(picture, win, 42, { polyEdge: 1, polyMode: 0 } ); + //var pixmap = X.AllocID(); + //X.CreatePixmap(pixmap, win, 32, 1000, 1000); + //var pix_pict = X.AllocID(); + //RenderCreatePicture(pix_pict, pixmap, 38, { polyEdge: 1, polyMode: 0 }); + //RenderFillRectangles(1, pix_pict, [0xffff, 0, 0, 0x8000], [0, 0, 1000, 1000]); var pic_grad = X.AllocID(); - RenderLinearGradient(pic_grad, [0,0], [100,100], [ [0, [0,0,0,0xffff]], [100, [0xffff, 0xffff, 0xffff, 0xffff]]]); + //RenderLinearGradient(pic_grad, [0,0], [1000,100], + //RenderRadialGradient(pic_grad, [0,0], [1000,100], 10, 1000, + RenderConicalGradient(pic_grad, [250,250], 360, + [ + [0, [0,0,0,0xffff ] ], + [0.1, [0xfff, 0, 0xffff, 0x8000] ] , + [0.25, [0xffff, 0, 0xfff, 0x8000] ] , + [0.5, [0xffff, 0, 0xffff, 0x8000] ] , + [1, [0xffff, 0xffff, 0, 0xffff] ] + ]); X.on('event', function(ev) { - console.log(ev); - RenderFillRectangles(1, picture, [0xffff, 0xffff, 0xffff, 0xffff], [0, 0, 500, 500]); + //console.log(ev); + //RenderFillRectangles(1, picture, [0xffff, 0xffff, 0xffff, 0xffff], [0, 0, 500, 500]); //RenderFillRectangles(1, picture, [0xffff, 0xffff, 0x0000, 0xffff], [10, 10, 50, 50]); - RenderTriangles(3, pix_pict, 500, 500, picture, 0, [250, 100, 100, 350, 400, 350]); - //RenderTriangles(3, pic_grad, 500, 500, picture, 0, [250, 100, 100, 350, 400, 350]); + + //RenderTriangles(3, pic_grad, 0, 0, picture, 0, [0, 0, 500, 0, 0, 500]); + //RenderTriangles(3, pic_grad, 0, 0, picture, 0, [0, 500, 500, 500, 500, 0]); + RenderTrapezoids(3, pic_grad, 0, 0, picture, 0, [0, 0, 0, 500, 500, 500, 0, 500]); + + /* + for(var i=0; i < 100; ++i) + { + var pts = []; + for (var coord = 0; coord < 6; coord++) + pts.push(Math.random()*1000); + RenderTriangles(3, pic_grad, Math.random()*600, Math.random()*500, picture, 0, pts); + //RenderTriangles(3, pic_grad, 0, 0, picture, 0, [0, 0, 1000, 0, 0, 1000]); + //RenderTriangles(3, pic_grad, 0, 0, picture, 0, [0, 1000, 1000, 1000, 1000, 0]); + //RenderTriangles(3, pic_grad, 500, 500, picture, 0, [0, 250, 100, 350, 400, 350]); + } + */ }); }); }