From 39afe27793d818e4e6c08910021ca6fcbbbc9409 Mon Sep 17 00:00:00 2001 From: Andrey Sidorov Date: Fri, 28 Mar 2014 17:44:27 +1100 Subject: [PATCH] add XRender error handling --- lib/ext/render.js | 112 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 18 deletions(-) diff --git a/lib/ext/render.js b/lib/ext/render.js index 71bcfbf..23416c9 100644 --- a/lib/ext/render.js +++ b/lib/ext/render.js @@ -1,6 +1,5 @@ - - var x11 = require('..'); +var xutil = require('../xutil'); // adding XRender functions manually from // http://cgit.freedesktop.org/xcb/proto/tree/src/render.xml?id=HEAD @@ -371,34 +370,98 @@ exports.requireExt = function(display, callback) var numGlyphs = glyphs.length; var imageBytes = 0; for (var i = 0; i < numGlyphs; i++) - imageBytes += glyphs[i].image.length; - var paddedLength = xutil.padded_length(imageBytes); - var len = numGlyphs * 4 + paddedLength / 4 + 3; + //imageBytes += glyphs[i].image.length; + imageBytes += xutil.padded_length(glyphs[i].image.length); + //var paddedLength = xutil.padded_length(imageBytes); + console.log(imageBytes); + var len = numGlyphs * 4 + imageBytes/4 + 3; // TODO: check length, use bigReq - X.pack_stream.pack('CCSLL', [ext.majorOpcode, 20, len, gsid, glyps.length]); + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 20, len, gsid, glyphs.length]); + console.log('CCSLL', [ext.majorOpcode, 20, len, gsid, glyphs.length]); + // + // BigReq: S + [ length ] replaced with SL + [ 0, length+1 ] + //X.pack_stream.pack('CCSLLL', [ext.majorOpcode, 20, 0, len+1, gsid, glyphs.length]); + //console.log('CCSLLL', [ext.majorOpcode, 20, 0, len+1, gsid, glyphs.length]); + + for (i = 0; i < numGlyphs; i++) { + var id = glyphs[i].id; + console.log('============= added glyph ', id, String.fromCharCode(id)); + X.pack_stream.pack('L', id); + } for (i = 0; i < numGlyphs; i++) - X.pack_stream.pack('L', glyph[i].id); - for (i = 0; i < numGlyphs; i++) - X.pack_stream.pack('SSssss', [glyph[i].width, glyph[i].height, glyph[i].x, glyph[i].y, glyph[i].offX, glyph[i].offY]); - for (i = 0; i < numGlyphs; i++) - X.pack_stream.write_queue.push(glyph[i].image); - var padLength = paddedLength - imageBytes; - X.pack_stream.write_queue.push(new Buffer(padLength)); + { + X.pack_stream.pack('SSssss', [glyphs[i].width, glyphs[i].height, glyphs[i].x, glyphs[i].y, glyphs[i].offX, glyphs[i].offY]); + console.log('SSssss', [glyphs[i].width, glyphs[i].height, glyphs[i].x, glyphs[i].y, glyphs[i].offX, glyphs[i].offY]); + } + + + for (i = 0; i < numGlyphs; i++) { + X.pack_stream.write_queue.push(glyphs[i].image); + //X.pack_stream.pack('a', [glyphs[i].image]); + var il = glyphs[i].image.length; + var pl = xutil.padded_length(il); + if (pl - il > 0) { + X.pack_stream.write_queue.push(new Buffer(pl - il)); + } + } + + //var padLength = paddedLength - imageBytes; + //if (padLength > 0) + // X.pack_stream.write_queue.push(new Buffer(padLength)); X.pack_stream.flush(); } //AddGlyphsFromPicture, opcode=21 (not in spec) // FreeGlyps - 22 - ext.CompositeGlyphs8 = function(op, src, dst, pictformat, gsid, srcX, srcY, dstX, dstY, glyphs) + // each GlyphEle: + // 1 byte - number of glyphs + // xxx + // int16 deltax, deltay + // + list of 8/16/32 byte indexes + // OR + // 255 + 0 + 0 + glyphsetId / font: + // CxxxssL, [255, 0, 0, glyphable] + // + // Each GlyphEle must be padded to 4 byte boundary + // + // glyphs as input: + // [ "just string (0,0) offset is used", [ 10, 10, "string offseted 10,10 from previous pen position" ], 1234567 ] 1234567 is glypfset id or FONT + + + var argnames = require('argnames'); + + ext.CompositeGlyphs8 = function(op, src, dst, maskFormat, gsid, srcX, srcY, glyphs) { + argnames.dump() + X.seq_num++; + var length = 7; + for (var i=0; i < glyphs.length; ++i) { + var g = glyphs[i]; + switch (typeof g) { + case 'string': + length += xutil.padded_length(g.length)/4 + 2; + } + } X.pack_stream.pack( - 'CCSCxxxLLLssssssSS', - [ext.majorOpcode, 8, 9, op, src, mask, dst, srcX, srcY, maskX, maskY, dstX, dstY, width, height] - ) - .flush(); + 'CCSCxxxLLLLss', + [ext.majorOpcode, 23, length, op, src, dst, maskFormat, gsid, srcX, srcY] + ); + debugger + console.log('CCSCxxxLLLLss', [ext.majorOpcode, 23, length, op, src, dst, maskFormat, gsid, srcX, srcY]); + for (var i=0; i < glyphs.length; ++i) { + var g = glyphs[i]; + switch (typeof g) { + case 'string': + debugger; + X.pack_stream.pack('Cxxxssp', [xutil.padded_length(g.length), 0, 0, g]); + console.log('Cxxxssp', [xutil.padded_length(g.length), 0, 0, g]); + break; + } + } + X.pack_stream.flush(); } @@ -435,5 +498,18 @@ exports.requireExt = function(display, callback) } callback(ext); }); + + [ + "PICTFORMAT argument does not name a defined PICTFORMAT", + "PICTURE argument does not name a defined PICTURE", + "PICTOP argument does not name a defined PICTOP", + "GLYPHSET argument does not name a defined GLYPHSET", + "GLYPH argument does not name a defined GLYPH in the glyphset" + ].forEach(function(desc, code) { + X.errorParsers[ext.firstError + code] = function(err) { + err.message = "XRender: a value for a " + desc; + }; + }); + }); }