Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 38 additions & 31 deletions lib/context2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ var canvas = require('./bindings')
, CanvasPattern = canvas.CanvasPattern
, ImageData = canvas.ImageData;

var parseCssFont = require('parse-css-font');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of this should be it's own PR, it also should remove the dependencies from the package.json...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realise that it would be part of the pull request.. that was not intentional.


var unitsCss = require('units-css');

/**
* Export `Context2d` as the module.
*/
Expand All @@ -38,6 +34,26 @@ var cache = {};

var baselines = ['alphabetic', 'top', 'bottom', 'middle', 'ideographic', 'hanging'];

/**
* Font RegExp helpers.
*/

var weights = 'normal|bold|bolder|lighter|[1-9]00'
, styles = 'normal|italic|oblique'
, units = 'px|pt|pc|in|cm|mm|%'
, string = '\'([^\']+)\'|"([^"]+)"|[\\w-]+';

/**
* Font parser RegExp;
*/

var fontre = new RegExp('^ *'
+ '(?:(' + weights + ') *)?'
+ '(?:(' + styles + ') *)?'
+ '([\\d\\.]+)(' + units + ') *'
+ '((?:' + string + ')( *, *(?:' + string + '))*)'
);

/**
* Parse font `str`.
*
Expand All @@ -46,51 +62,42 @@ var baselines = ['alphabetic', 'top', 'bottom', 'middle', 'ideographic', 'hangin
* @api private
*/

var parseFont = exports.parseFont = function(str) {
var parsedFont;
var parseFont = exports.parseFont = function(str){
var font = {}
, captures = fontre.exec(str);

// Try to parse the font string using parse-css-font.
// It will throw an exception if it fails.
try {
parsedFont = parseCssFont(str);
}
catch (e) {
// Invalid
return;
}
// Invalid
if (!captures) return;

// Cached
if (cache[str]) return cache[str];

// Parse size into value and unit using units-css
var size = unitsCss.parse(parsedFont.size);
// Populate font object
font.weight = captures[1] || 'normal';
font.style = captures[2] || 'normal';
font.size = parseFloat(captures[3]);
font.unit = captures[4];
font.family = captures[5].replace(/["']/g, '').split(',').map(function (family) {
return family.trim();
}).join(',');

// TODO: dpi
// TODO: remaining unit conversion
switch (size.unit) {
switch (font.unit) {
case 'pt':
size.value /= .75;
font.size /= .75;
break;
case 'in':
size.value *= 96;
font.size *= 96;
break;
case 'mm':
size.value *= 96.0 / 25.4;
font.size *= 96.0 / 25.4;
break;
case 'cm':
size.value *= 96.0 / 2.54;
font.size *= 96.0 / 2.54;
break;
}

// Populate font object
var font = {
weight: parsedFont.weight,
style: parsedFont.style,
size: size.value,
unit: size.unit,
family: parsedFont.family.join(',')
};

return cache[str] = font;
};

Expand Down
23 changes: 23 additions & 0 deletions src/Image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Image::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {

// Prototype
Local<ObjectTemplate> proto = ctor->PrototypeTemplate();
Nan::SetAccessor(proto, Nan::New("rawData").ToLocalChecked(), GetRawData);
Nan::SetAccessor(proto, Nan::New("source").ToLocalChecked(), GetSource, SetSource);
Nan::SetAccessor(proto, Nan::New("complete").ToLocalChecked(), GetComplete);
Nan::SetAccessor(proto, Nan::New("width").ToLocalChecked(), GetWidth);
Expand Down Expand Up @@ -134,6 +135,28 @@ NAN_GETTER(Image::GetSource) {
info.GetReturnValue().Set(Nan::New<String>(img->filename ? img->filename : "").ToLocalChecked());
}


/*
* Get raw data.
*/

NAN_GETTER(Image::GetRawData) {
Image *img = Nan::ObjectWrap::Unwrap<Image>(info.This());
if (img->_surface) {
// Return raw ARGB data -- just a memcpy()
cairo_surface_t *surface = img->_surface;
cairo_surface_flush(surface);
const unsigned char *data = cairo_image_surface_get_data(surface);

unsigned int nBytes = img->width * img->height * 4;
Local<Object> buf = Nan::CopyBuffer(reinterpret_cast<const char*>(data), nBytes).ToLocalChecked();
info.GetReturnValue().Set(buf);
} else {
info.GetReturnValue().Set(Nan::Undefined());
}
return;
}

/*
* Clean up assets and variables.
*/
Expand Down
1 change: 1 addition & 0 deletions src/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Image: public Nan::ObjectWrap {
static Nan::Persistent<FunctionTemplate> constructor;
static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
static NAN_METHOD(New);
static NAN_GETTER(GetRawData);
static NAN_GETTER(GetSource);
static NAN_GETTER(GetOnload);
static NAN_GETTER(GetOnerror);
Expand Down
8 changes: 8 additions & 0 deletions test/image.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ describe('Image', function () {
assert.equal(onloadCalled, 1);
});

it('Image#rawData', function() {
var img = new Image();
img.src = png_clock;
var buf = img.rawData;
assert.ok(buf instanceof Buffer);
assert.strictEqual(409600, img.rawData.length);
});

it('Image#onerror', function () {
var img = new Image
, error
Expand Down