diff --git a/CHANGELOG.md b/CHANGELOG.md index 77cc5db8e..f1de45c45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ project adheres to [Semantic Versioning](http://semver.org/). ================== ### Changed ### Added +* Support for links in PDFs ### Fixed diff --git a/Readme.md b/Readme.md index 7e7b88ba1..c614645fd 100644 --- a/Readme.md +++ b/Readme.md @@ -521,6 +521,15 @@ ctx.addPage(400, 800) ctx.fillText('Hello World 2', 50, 80) ``` +It is possible to add hyperlinks use `.beginTag(uri)` and `.closeTag()`: + +```js +ctx.beginTag("https://google.com") +ctx.font = '22px Helvetica' +ctx.fillText('Hello World', 50, 80) +ctx.closeTag() +``` + See also: * [Image#dataMode](#imagedatamode) for embedding JPEGs in PDFs diff --git a/examples/pdf-link.js b/examples/pdf-link.js new file mode 100644 index 000000000..9fb981ff4 --- /dev/null +++ b/examples/pdf-link.js @@ -0,0 +1,19 @@ +const fs = require('fs') +const Canvas = require('..') + +const canvas = Canvas.createCanvas(400, 200, 'pdf') +const ctx = canvas.getContext('2d') + +let y = 80 +let x = 50 + +ctx.beginTag("https://google.com") +ctx.font = '22px Helvetica' +ctx.fillText('node-canvas pdf', x, y) +ctx.closeTag() + +fs.writeFile('out.pdf', canvas.toBuffer(), function (err) { + if (err) throw err + + console.log('created out.pdf') +}) diff --git a/src/CanvasRenderingContext2d.cc b/src/CanvasRenderingContext2d.cc index 56e68d899..fed7789fc 100644 --- a/src/CanvasRenderingContext2d.cc +++ b/src/CanvasRenderingContext2d.cc @@ -134,6 +134,10 @@ Context2d::Initialize(Napi::Env& env, Napi::Object& exports) { InstanceMethod<&Context2d::CreatePattern>("createPattern"), InstanceMethod<&Context2d::CreateLinearGradient>("createLinearGradient"), InstanceMethod<&Context2d::CreateRadialGradient>("createRadialGradient"), + #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 16, 0) + InstanceMethod<&Context2d::BeginTag>("beginTag"), + InstanceMethod<&Context2d::CloseTag>("closeTag"), + #endif InstanceAccessor<&Context2d::GetFormat>("pixelFormat"), InstanceAccessor<&Context2d::GetPatternQuality, &Context2d::SetPatternQuality>("patternQuality"), InstanceAccessor<&Context2d::GetImageSmoothingEnabled, &Context2d::SetImageSmoothingEnabled>("imageSmoothingEnabled"), @@ -3354,3 +3358,29 @@ Context2d::Ellipse(const Napi::CallbackInfo& info) { } cairo_set_matrix(ctx, &save_matrix); } + +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 16, 0) + +/* + * Open and close a link tag + */ + +void +Context2d::BeginTag(const Napi::CallbackInfo& info) { + Napi::String strValue; + if (!info[0].ToString().UnwrapTo(&strValue)) return; + + std::string str = strValue.Utf8Value(); + std::string uri = "uri='" + str + "'"; + + cairo_t *ctx = context(); + cairo_tag_begin(ctx, CAIRO_TAG_LINK, uri.c_str()); +} + +void +Context2d::CloseTag(const Napi::CallbackInfo& info) { + cairo_t *ctx = context(); + cairo_tag_end(ctx, CAIRO_TAG_LINK); +} + +#endif diff --git a/src/CanvasRenderingContext2d.h b/src/CanvasRenderingContext2d.h index 745106e2d..8bd062c36 100644 --- a/src/CanvasRenderingContext2d.h +++ b/src/CanvasRenderingContext2d.h @@ -178,6 +178,8 @@ class Context2d : public Napi::ObjectWrap { void SetFont(const Napi::CallbackInfo& info, const Napi::Value& value); void SetTextBaseline(const Napi::CallbackInfo& info, const Napi::Value& value); void SetTextAlign(const Napi::CallbackInfo& info, const Napi::Value& value); + void BeginTag(const Napi::CallbackInfo& info); + void CloseTag(const Napi::CallbackInfo& info); inline void setContext(cairo_t *ctx) { _context = ctx; } inline cairo_t *context(){ return _context; } inline Canvas *canvas(){ return _canvas; }