@gjsify/canvas2d-core 0.4.21 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/canvas-rendering-context-2d.js +1 -1
- package/lib/esm/context/drawing.js +1 -0
- package/lib/esm/context/factories.js +1 -0
- package/lib/esm/context/index.js +1 -0
- package/lib/esm/context/path-ops.js +1 -0
- package/lib/esm/context/pixels.js +1 -0
- package/lib/esm/context/text-rendering.js +1 -0
- package/lib/esm/context/transforms.js +1 -0
- package/lib/types/canvas-rendering-context-2d.d.ts +18 -94
- package/lib/types/context/drawing.d.ts +25 -0
- package/lib/types/context/factories.d.ts +11 -0
- package/lib/types/context/index.d.ts +7 -0
- package/lib/types/context/path-ops.d.ts +19 -0
- package/lib/types/context/pixels.d.ts +12 -0
- package/lib/types/context/text-rendering.d.ts +11 -0
- package/lib/types/context/transforms.d.ts +16 -0
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{asCairoPattern as e}from"./cairo-types.js";import{COMPOSITE_OP_MAP as t,LINE_CAP_MAP as n,LINE_JOIN_MAP as r,cairoArcTo as i,cairoEllipse as a,cairoRoundRect as o,quadraticToCubic as s}from"./cairo-utils.js";import{parseColor as c}from"./color.js";import{CanvasGradient as l}from"./canvas-gradient.js";import{Path2D as u}from"./canvas-path.js";import{isCanvasImageSource as d,isPixbufImageSource as f}from"./dom-types.js";import{CanvasPattern as p}from"./canvas-pattern.js";import{cloneState as m,createDefaultState as h}from"./canvas-state.js";import{OurImageData as g}from"./image-data.js";import _ from"cairo";import v from"gi://Gdk?version=4.0";import y from"gi://GdkPixbuf";import b from"gi://Pango";import x from"gi://PangoCairo";var CanvasRenderingContext2D=class{constructor(e,t){this._stateStack=[],this.canvas=e,this._surfaceWidth=e.width||300,this._surfaceHeight=e.height||150,this._surface=new _.ImageSurface(_.Format.ARGB32,this._surfaceWidth,this._surfaceHeight),this._ctx=new _.Context(this._surface),this._state=h()}_ensureSurface(){let e=this.canvas.width||300,t=this.canvas.height||150;(e!==this._surfaceWidth||t!==this._surfaceHeight)&&(this._ctx.$dispose(),this._surface.finish(),this._surfaceWidth=e,this._surfaceHeight=t,this._surface=new _.ImageSurface(_.Format.ARGB32,e,t),this._ctx=new _.Context(this._surface),this._stateStack=[])}_resetState(){this._state=h(),this._stateStack=[]}_applyFillStyle(){let e=this._state.fillStyle;if(typeof e==`string`){let e=this._state.fillColor,t=e.a*this._state.globalAlpha;this._ctx.setSourceRGBA(e.r,e.g,e.b,t)}else e instanceof l?this._ctx.setSource(e._getCairoPattern()):e instanceof p&&(this._ctx.setSource(e._getCairoPattern()),this._applyPatternFilter())}_applyStrokeStyle(){let e=this._state.strokeStyle;if(typeof e==`string`){let e=this._state.strokeColor,t=e.a*this._state.globalAlpha;this._ctx.setSourceRGBA(e.r,e.g,e.b,t)}else e instanceof l?this._ctx.setSource(e._getCairoPattern()):e instanceof p&&(this._ctx.setSource(e._getCairoPattern()),this._applyPatternFilter())}_applyPatternFilter(){let t=e(this._ctx.getSource?.());if(!t)return;let n;n=this._state.imageSmoothingEnabled?this._state.imageSmoothingQuality===`high`?_.Filter.BEST:_.Filter.BILINEAR:_.Filter.NEAREST,t.setFilter(n)}_applyLineStyle(){this._ctx.setLineWidth(this._state.lineWidth),this._ctx.setLineCap(n[this._state.lineCap]),this._ctx.setLineJoin(r[this._state.lineJoin]),this._ctx.setMiterLimit(this._state.miterLimit),this._ctx.setDash(this._state.lineDash,this._state.lineDashOffset)}_applyCompositing(){let e=t[this._state.globalCompositeOperation];e!==void 0&&this._ctx.setOperator(e)}_getSurface(){return this._surface}_hasShadow(){if(this._state.shadowBlur===0&&this._state.shadowOffsetX===0&&this._state.shadowOffsetY===0)return!1;let e=c(this._state.shadowColor);return e!==null&&e.a>0}_deviceToUserDistance(e,t){let n=this._ctx.userToDevice(0,0),r=this._ctx.userToDevice(1,0),i=this._ctx.userToDevice(0,1),a=(r[0]??0)-(n[0]??0),o=(r[1]??0)-(n[1]??0),s=(i[0]??0)-(n[0]??0),c=(i[1]??0)-(n[1]??0),l=a*c-o*s;return Math.abs(l)<1e-10?[e,t]:[(c*e-s*t)/l,(-o*e+a*t)/l]}_renderShadow(e){}save(){this._ensureSurface(),this._stateStack.push(m(this._state)),this._ctx.save()}restore(){this._ensureSurface();let e=this._stateStack.pop();e&&(this._state=e,this._ctx.restore())}translate(e,t){this._ensureSurface(),this._ctx.translate(e,t)}rotate(e){this._ensureSurface(),this._ctx.rotate(e)}scale(e,t){this._ensureSurface(),this._ctx.scale(e,t)}transform(e,t,n,r,i,a){if(this._ensureSurface(),!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(a))return;let o=i,s=a,c=Math.hypot(e,t),l=Math.hypot(n,r),u=Math.atan2(t,e);this._ctx.translate(o,s),u!==0&&this._ctx.rotate(u),(c!==1||l!==1)&&this._ctx.scale(c,l)}setTransform(e,t,n,r,i,a){if(this._ensureSurface(),typeof e==`object`&&e){let t=e;this._ctx.identityMatrix(),this.transform(t.a??t.m11??1,t.b??t.m12??0,t.c??t.m21??0,t.d??t.m22??1,t.e??t.m41??0,t.f??t.m42??0)}else typeof e==`number`?(this._ctx.identityMatrix(),this.transform(e,t,n,r,i,a)):this._ctx.identityMatrix()}getTransform(){let e=this._ctx.userToDevice(0,0),t=this._ctx.userToDevice(1,0),n=this._ctx.userToDevice(0,1),r=e[0]??0,i=e[1]??0,a=(t[0]??0)-r,o=(t[1]??0)-i,s=(n[0]??0)-r,c=(n[1]??0)-i,l=globalThis.DOMMatrix;return typeof l==`function`?new l([a,o,s,c,r,i]):{a,b:o,c:s,d:c,e:r,f:i,m11:a,m12:o,m13:0,m14:0,m21:s,m22:c,m23:0,m24:0,m31:0,m32:0,m33:1,m34:0,m41:r,m42:i,m43:0,m44:1,is2D:!0,isIdentity:a===1&&o===0&&s===0&&c===1&&r===0&&i===0}}resetTransform(){this._ensureSurface(),this._ctx.identityMatrix()}get fillStyle(){return this._state.fillStyle}set fillStyle(e){if(typeof e==`string`){let t=c(e);t&&(this._state.fillStyle=e,this._state.fillColor=t)}else this._state.fillStyle=e}get strokeStyle(){return this._state.strokeStyle}set strokeStyle(e){if(typeof e==`string`){let t=c(e);t&&(this._state.strokeStyle=e,this._state.strokeColor=t)}else this._state.strokeStyle=e}get lineWidth(){return this._state.lineWidth}set lineWidth(e){e>0&&isFinite(e)&&(this._state.lineWidth=e)}get lineCap(){return this._state.lineCap}set lineCap(e){(e===`butt`||e===`round`||e===`square`)&&(this._state.lineCap=e)}get lineJoin(){return this._state.lineJoin}set lineJoin(e){(e===`miter`||e===`round`||e===`bevel`)&&(this._state.lineJoin=e)}get miterLimit(){return this._state.miterLimit}set miterLimit(e){e>0&&isFinite(e)&&(this._state.miterLimit=e)}get globalAlpha(){return this._state.globalAlpha}set globalAlpha(e){e>=0&&e<=1&&isFinite(e)&&(this._state.globalAlpha=e)}get globalCompositeOperation(){return this._state.globalCompositeOperation}set globalCompositeOperation(e){t[e]!==void 0&&(this._state.globalCompositeOperation=e)}get imageSmoothingEnabled(){return this._state.imageSmoothingEnabled}set imageSmoothingEnabled(e){this._state.imageSmoothingEnabled=!!e}get imageSmoothingQuality(){return this._state.imageSmoothingQuality}set imageSmoothingQuality(e){(e===`low`||e===`medium`||e===`high`)&&(this._state.imageSmoothingQuality=e)}setLineDash(e){e.some(e=>e<0||!isFinite(e))||(this._state.lineDash=[...e])}getLineDash(){return[...this._state.lineDash]}get lineDashOffset(){return this._state.lineDashOffset}set lineDashOffset(e){isFinite(e)&&(this._state.lineDashOffset=e)}get shadowColor(){return this._state.shadowColor}set shadowColor(e){this._state.shadowColor=e}get shadowBlur(){return this._state.shadowBlur}set shadowBlur(e){e>=0&&isFinite(e)&&(this._state.shadowBlur=e)}get shadowOffsetX(){return this._state.shadowOffsetX}set shadowOffsetX(e){isFinite(e)&&(this._state.shadowOffsetX=e)}get shadowOffsetY(){return this._state.shadowOffsetY}set shadowOffsetY(e){isFinite(e)&&(this._state.shadowOffsetY=e)}get font(){return this._state.font}set font(e){this._state.font=e}get textAlign(){return this._state.textAlign}set textAlign(e){this._state.textAlign=e}get textBaseline(){return this._state.textBaseline}set textBaseline(e){this._state.textBaseline=e}get direction(){return this._state.direction}set direction(e){this._state.direction=e}beginPath(){this._ensureSurface(),this._ctx.newPath()}moveTo(e,t){this._ensureSurface(),this._ctx.moveTo(e,t)}lineTo(e,t){this._ensureSurface(),this._ctx.lineTo(e,t)}closePath(){this._ensureSurface(),this._ctx.closePath()}bezierCurveTo(e,t,n,r,i,a){this._ensureSurface(),this._ctx.curveTo(e,t,n,r,i,a)}quadraticCurveTo(e,t,n,r){this._ensureSurface();let i,a;this._ctx.hasCurrentPoint()?[i,a]=this._ctx.getCurrentPoint():(i=e,a=t);let{cp1x:o,cp1y:c,cp2x:l,cp2y:u}=s(i,a,e,t,n,r);this._ctx.curveTo(o,c,l,u,n,r)}arc(e,t,n,r,i,a=!1){if(this._ensureSurface(),Math.abs(i-r)>=2*Math.PI){this._ctx.arc(e,t,n,0,2*Math.PI);return}a?this._ctx.arcNegative(e,t,n,r,i):this._ctx.arc(e,t,n,r,i)}arcTo(e,t,n,r,a){this._ensureSurface();let o,s;this._ctx.hasCurrentPoint()?[o,s]=this._ctx.getCurrentPoint():(o=e,s=t,this._ctx.moveTo(e,t)),i(this._ctx,o,s,e,t,n,r,a)}ellipse(e,t,n,r,i,o,s,c=!1){if(this._ensureSurface(),n<0||r<0)throw RangeError(`The radii provided are negative`);a(this._ctx,e,t,n,r,i,o,s,c)}rect(e,t,n,r){this._ensureSurface(),this._ctx.rectangle(e,t,n,r)}roundRect(e,t,n,r,i=0){this._ensureSurface(),o(this._ctx,e,t,n,r,i)}fill(e,t){this._ensureSurface(),this._applyCompositing(),this._applyFillStyle();let n;e instanceof u?(this._ctx.newPath(),e._replayOnCairo(this._ctx),n=t):n=e,this._ctx.setFillRule(n===`evenodd`?_.FillRule.EVEN_ODD:_.FillRule.WINDING),this._ctx.fillPreserve()}stroke(e){this._ensureSurface(),this._applyCompositing(),this._applyStrokeStyle(),this._applyLineStyle(),e instanceof u&&(this._ctx.newPath(),e._replayOnCairo(this._ctx)),this._ctx.strokePreserve()}fillRect(e,t,n,r){this._ensureSurface(),this._applyCompositing();let i=this._ctx.copyPath();this._hasShadow()&&this._renderShadow(()=>{this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill()}),this._applyFillStyle(),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill(),this._ctx.newPath(),this._ctx.appendPath(i)}strokeRect(e,t,n,r){this._ensureSurface(),this._applyCompositing();let i=this._ctx.copyPath();this._hasShadow()&&this._renderShadow(()=>{this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.stroke()}),this._applyStrokeStyle(),this._applyLineStyle(),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.stroke(),this._ctx.newPath(),this._ctx.appendPath(i)}clearRect(e,t,n,r){this._ensureSurface();let i=this._ctx.copyPath();this._ctx.save(),this._ctx.setOperator(_.Operator.CLEAR),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill(),this._ctx.restore(),this._ctx.newPath(),this._ctx.appendPath(i)}clip(e,t){this._ensureSurface();let n;e instanceof u?(this._ctx.newPath(),e._replayOnCairo(this._ctx),n=t):n=e,this._ctx.setFillRule(n===`evenodd`?_.FillRule.EVEN_ODD:_.FillRule.WINDING),this._ctx.clip()}isPointInPath(e,t,n,r){this._ensureSurface();let i,a,o;return e instanceof u?(this._ctx.newPath(),e._replayOnCairo(this._ctx),i=t,a=n,o=r):(i=e,a=t,o=n),this._ctx.setFillRule(o===`evenodd`?_.FillRule.EVEN_ODD:_.FillRule.WINDING),this._ctx.inFill(i,a)}isPointInStroke(e,t,n){return this._ensureSurface(),this._applyLineStyle(),e instanceof u?(this._ctx.newPath(),e._replayOnCairo(this._ctx),this._ctx.inStroke(t,n)):this._ctx.inStroke(e,t)}createLinearGradient(e,t,n,r){return new l(`linear`,e,t,n,r)}createRadialGradient(e,t,n,r,i,a){return new l(`radial`,e,t,r,i,n,a)}createPattern(e,t){return p.create(e,t)}createImageData(e,t){return typeof e==`number`?new g(Math.abs(e),Math.abs(t)):new g(e.width,e.height)}getImageData(e,t,n,r){this._ensureSurface(),this._surface.flush();let i=v.pixbuf_get_from_surface(this._surface,e,t,n,r);if(!i)return new g(n,r);let a=i.get_pixels(),o=i.get_has_alpha(),s=i.get_rowstride(),c=i.get_n_channels(),l=new Uint8ClampedArray(n*r*4);for(let e=0;e<r;e++)for(let t=0;t<n;t++){let r=e*s+t*c,i=(e*n+t)*4;l[i]=a[r],l[i+1]=a[r+1],l[i+2]=a[r+2],l[i+3]=o?a[r+3]:255}return new g(l,n,r)}putImageData(e,t,n,r,i,a,o){this._ensureSurface();let s=r??0,c=i??0,l=a??e.width,u=o??e.height,d=e.data,f=e.width,p=new Uint8Array(l*u*4);for(let e=0;e<u;e++)for(let t=0;t<l;t++){let n=((c+e)*f+(s+t))*4,r=(e*l+t)*4;p[r]=d[n],p[r+1]=d[n+1],p[r+2]=d[n+2],p[r+3]=d[n+3]}let m=y.Pixbuf.new_from_bytes(p,y.Colorspace.RGB,!0,8,l,u,l*4);this._ctx.save(),this._ctx.setOperator(_.Operator.SOURCE),v.cairo_set_source_pixbuf(this._ctx,m,t+s,n+c),this._ctx.rectangle(t+s,n+c,l,u),this._ctx.fill(),this._ctx.restore()}drawImage(t,n,r,i,a,o,s,c,l){this._ensureSurface(),this._applyCompositing();let u,d,f,p,m,h,g,y,b=this._getDrawImageSource(t);if(!b)return;let{pixbuf:x,imgWidth:S,imgHeight:C}=b;if(i===void 0?(u=0,d=0,f=S,p=C,m=n,h=r,g=S,y=C):o===void 0?(u=0,d=0,f=S,p=C,m=n,h=r,g=i,y=a):(u=n,d=r,f=i,p=a,m=o,h=s,g=c,y=l),!Number.isFinite(u)||!Number.isFinite(d)||!Number.isFinite(f)||!Number.isFinite(p)||!Number.isFinite(m)||!Number.isFinite(h)||!Number.isFinite(g)||!Number.isFinite(y)||f===0||p===0||g===0||y===0)return;this._ctx.save(),this._ctx.rectangle(m,h,g,y),this._ctx.clip(),this._ctx.translate(m,h),this._ctx.scale(g/f,y/p),this._ctx.translate(-u,-d),v.cairo_set_source_pixbuf(this._ctx,x,0,0);let w=e(this._ctx.getSource?.());if(w){let e;e=this._state.imageSmoothingEnabled?this._state.imageSmoothingQuality===`high`?_.Filter.BEST:_.Filter.BILINEAR:_.Filter.NEAREST,w.setFilter(e)}this._state.globalAlpha<1?this._ctx.paintWithAlpha(this._state.globalAlpha):this._ctx.paint(),this._ctx.restore()}_getDrawImageSource(e){if(f(e)){let t=e._pixbuf;return{pixbuf:t,imgWidth:t.get_width(),imgHeight:t.get_height()}}if(d(e)){let t=e.width??0,n=e.height??0;if(!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0)return null;let r=e.getContext(`2d`);if(r&&typeof r._getSurface==`function`){let e=r._getSurface();e.flush();let i=v.pixbuf_get_from_surface(e,0,0,t,n);if(i)return{pixbuf:i,imgWidth:t,imgHeight:n}}}return null}_createTextLayout(e){let t=x.create_layout(this._ctx);t.set_text(e,-1),t.get_context().set_base_dir(b.Direction.LTR),t.context_changed();let n=this._parseFontToDescription(this._state.font);return t.set_font_description(n),t}_parseFontToDescription(e){let t=e.match(/^\s*(italic|oblique|normal)?\s*(small-caps|normal)?\s*(bold|bolder|lighter|[1-9]00|normal)?\s*(\d+(?:\.\d+)?)(px|pt|em|rem|%)?\s*(?:\/\S+)?\s*(.+)?$/i);if(!t)return b.font_description_from_string(e);let n=t[1]||``,r=t[3]||``,i=parseFloat(t[4])||10,a=(t[5]||`px`).toLowerCase(),o=(t[6]||`sans-serif`).replace(/['"]/g,``).trim();a===`pt`?i=i*96/72:a===`em`||a===`rem`?i*=16:a===`%`&&(i=i/100*16);let s=o;n===`italic`?s+=` Italic`:n===`oblique`&&(s+=` Oblique`),r===`bold`||r===`bolder`||parseInt(r)>=600?s+=` Bold`:(r===`lighter`||parseInt(r)>0&&parseInt(r)<=300)&&(s+=` Light`);let c=b.font_description_from_string(s);return c.set_absolute_size(i*b.SCALE),c}_getTextAlignOffset(e){let[,t]=e.get_pixel_extents(),n=t.width;switch(this._state.textAlign){case`center`:return-n/2;case`right`:case`end`:return-n;default:return 0}}_getTextBaselineOffset(e){let t=e.get_font_description()||this._parseFontToDescription(this._state.font),n=e.get_context().get_metrics(t,null),r=n.get_ascent()/b.SCALE,i=n.get_descent()/b.SCALE,a=r+i;switch(this._state.textBaseline){case`top`:return 0;case`hanging`:return-(r*.2);case`middle`:return-(a/2);case`alphabetic`:return-r;case`ideographic`:return-(r+i*.5);case`bottom`:return-a;default:return-r}}fillText(e,t,n,r){this._ensureSurface(),this._applyCompositing();let i=this._createTextLayout(e),a=this._getTextAlignOffset(i),o=this._getTextBaselineOffset(i);if(this._hasShadow()){let e=c(this._state.shadowColor);if(e){let[r,s]=this._deviceToUserDistance(this._state.shadowOffsetX,this._state.shadowOffsetY),c=this._state.shadowBlur,l;if(c>0){let[t]=this._deviceToUserDistance(c,0),[,n]=this._deviceToUserDistance(0,c);l=[[r,s,e.a],[r+t,s,e.a*.5],[r-t,s,e.a*.5],[r,s+n,e.a*.5],[r,s-n,e.a*.5]]}else l=[[r,s,e.a]];let u=this._state.imageSmoothingEnabled?_.Antialias.DEFAULT:_.Antialias.NONE;for(let[r,s,c]of l)this._ctx.save(),this._ctx.setAntialias(u),this._ctx.setSourceRGBA(e.r,e.g,e.b,c),this._ctx.moveTo(t+a+r,n+o+s),x.show_layout(this._ctx,i),this._ctx.restore()}}this._applyFillStyle(),this._ctx.save(),this._ctx.setAntialias(this._state.imageSmoothingEnabled?_.Antialias.DEFAULT:_.Antialias.NONE),this._ctx.moveTo(t+a,n+o),x.show_layout(this._ctx,i),this._ctx.restore()}strokeText(e,t,n,r){this._ensureSurface(),this._applyCompositing(),this._applyStrokeStyle(),this._applyLineStyle();let i=this._createTextLayout(e),a=this._getTextAlignOffset(i),o=this._getTextBaselineOffset(i);this._ctx.save(),this._ctx.setAntialias(this._state.imageSmoothingEnabled?_.Antialias.DEFAULT:_.Antialias.NONE),this._ctx.moveTo(t+a,n+o),x.layout_path(this._ctx,i),this._ctx.stroke(),this._ctx.restore()}measureText(e){this._ensureSurface();let t=this._createTextLayout(e),[n,r]=t.get_pixel_extents(),i=t.get_baseline()/b.SCALE,a=Math.max(0,i-n.y),o=Math.max(0,n.y+n.height-i),s=t.get_font_description()||this._parseFontToDescription(this._state.font),c=t.get_context().get_metrics(s,null),l=c.get_ascent()/b.SCALE,u=c.get_descent()/b.SCALE;return{width:r.width,actualBoundingBoxAscent:a,actualBoundingBoxDescent:o,actualBoundingBoxLeft:Math.max(0,-n.x),actualBoundingBoxRight:n.x+n.width,fontBoundingBoxAscent:l,fontBoundingBoxDescent:u,alphabeticBaseline:0,emHeightAscent:l,emHeightDescent:u,hangingBaseline:l*.8,ideographicBaseline:-u}}_toDataURL(e,t){this._surface.flush();let n=imports.gi.Gio,r=imports.gi.GLib,[,i]=r.file_open_tmp(`canvas-XXXXXX.png`);try{this._surface.writeToPNG(i);let[,e]=n.File.new_for_path(i).load_contents(null);return`data:image/png;base64,${r.base64_encode(e)}`}finally{try{r.unlink(i)}catch{}}}_dispose(){this._ctx.$dispose(),this._surface.finish()}};export{CanvasRenderingContext2D};
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{asCairoPattern as e}from"./cairo-types.js";import{COMPOSITE_OP_MAP as t,LINE_CAP_MAP as n,LINE_JOIN_MAP as r}from"./cairo-utils.js";import{parseColor as i}from"./color.js";import{CanvasGradient as a}from"./canvas-gradient.js";import{CanvasPattern as o}from"./canvas-pattern.js";import{installAllContextMethods as s}from"./context/index.js";import{cloneState as c,createDefaultState as l}from"./canvas-state.js";import u from"cairo";var CanvasRenderingContext2D=class{constructor(e,t){this._stateStack=[],this.canvas=e,this._surfaceWidth=e.width||300,this._surfaceHeight=e.height||150,this._surface=new u.ImageSurface(u.Format.ARGB32,this._surfaceWidth,this._surfaceHeight),this._ctx=new u.Context(this._surface),this._state=l()}_ensureSurface(){let e=this.canvas.width||300,t=this.canvas.height||150;(e!==this._surfaceWidth||t!==this._surfaceHeight)&&(this._ctx.$dispose(),this._surface.finish(),this._surfaceWidth=e,this._surfaceHeight=t,this._surface=new u.ImageSurface(u.Format.ARGB32,e,t),this._ctx=new u.Context(this._surface),this._stateStack=[])}_resetState(){this._state=l(),this._stateStack=[]}_applyFillStyle(){let e=this._state.fillStyle;if(typeof e==`string`){let e=this._state.fillColor,t=e.a*this._state.globalAlpha;this._ctx.setSourceRGBA(e.r,e.g,e.b,t)}else e instanceof a?this._ctx.setSource(e._getCairoPattern()):e instanceof o&&(this._ctx.setSource(e._getCairoPattern()),this._applyPatternFilter())}_applyStrokeStyle(){let e=this._state.strokeStyle;if(typeof e==`string`){let e=this._state.strokeColor,t=e.a*this._state.globalAlpha;this._ctx.setSourceRGBA(e.r,e.g,e.b,t)}else e instanceof a?this._ctx.setSource(e._getCairoPattern()):e instanceof o&&(this._ctx.setSource(e._getCairoPattern()),this._applyPatternFilter())}_applyPatternFilter(){let t=e(this._ctx.getSource?.());if(!t)return;let n;n=this._state.imageSmoothingEnabled?this._state.imageSmoothingQuality===`high`?u.Filter.BEST:u.Filter.BILINEAR:u.Filter.NEAREST,t.setFilter(n)}_applyLineStyle(){this._ctx.setLineWidth(this._state.lineWidth),this._ctx.setLineCap(n[this._state.lineCap]),this._ctx.setLineJoin(r[this._state.lineJoin]),this._ctx.setMiterLimit(this._state.miterLimit),this._ctx.setDash(this._state.lineDash,this._state.lineDashOffset)}_applyCompositing(){let e=t[this._state.globalCompositeOperation];e!==void 0&&this._ctx.setOperator(e)}_getSurface(){return this._surface}_hasShadow(){if(this._state.shadowBlur===0&&this._state.shadowOffsetX===0&&this._state.shadowOffsetY===0)return!1;let e=i(this._state.shadowColor);return e!==null&&e.a>0}_deviceToUserDistance(e,t){let n=this._ctx.userToDevice(0,0),r=this._ctx.userToDevice(1,0),i=this._ctx.userToDevice(0,1),a=(r[0]??0)-(n[0]??0),o=(r[1]??0)-(n[1]??0),s=(i[0]??0)-(n[0]??0),c=(i[1]??0)-(n[1]??0),l=a*c-o*s;return Math.abs(l)<1e-10?[e,t]:[(c*e-s*t)/l,(-o*e+a*t)/l]}_renderShadow(e){}save(){this._ensureSurface(),this._stateStack.push(c(this._state)),this._ctx.save()}restore(){this._ensureSurface();let e=this._stateStack.pop();e&&(this._state=e,this._ctx.restore())}get fillStyle(){return this._state.fillStyle}set fillStyle(e){if(typeof e==`string`){let t=i(e);t&&(this._state.fillStyle=e,this._state.fillColor=t)}else this._state.fillStyle=e}get strokeStyle(){return this._state.strokeStyle}set strokeStyle(e){if(typeof e==`string`){let t=i(e);t&&(this._state.strokeStyle=e,this._state.strokeColor=t)}else this._state.strokeStyle=e}get lineWidth(){return this._state.lineWidth}set lineWidth(e){e>0&&isFinite(e)&&(this._state.lineWidth=e)}get lineCap(){return this._state.lineCap}set lineCap(e){(e===`butt`||e===`round`||e===`square`)&&(this._state.lineCap=e)}get lineJoin(){return this._state.lineJoin}set lineJoin(e){(e===`miter`||e===`round`||e===`bevel`)&&(this._state.lineJoin=e)}get miterLimit(){return this._state.miterLimit}set miterLimit(e){e>0&&isFinite(e)&&(this._state.miterLimit=e)}get globalAlpha(){return this._state.globalAlpha}set globalAlpha(e){e>=0&&e<=1&&isFinite(e)&&(this._state.globalAlpha=e)}get globalCompositeOperation(){return this._state.globalCompositeOperation}set globalCompositeOperation(e){t[e]!==void 0&&(this._state.globalCompositeOperation=e)}get imageSmoothingEnabled(){return this._state.imageSmoothingEnabled}set imageSmoothingEnabled(e){this._state.imageSmoothingEnabled=!!e}get imageSmoothingQuality(){return this._state.imageSmoothingQuality}set imageSmoothingQuality(e){(e===`low`||e===`medium`||e===`high`)&&(this._state.imageSmoothingQuality=e)}setLineDash(e){e.some(e=>e<0||!isFinite(e))||(this._state.lineDash=[...e])}getLineDash(){return[...this._state.lineDash]}get lineDashOffset(){return this._state.lineDashOffset}set lineDashOffset(e){isFinite(e)&&(this._state.lineDashOffset=e)}get shadowColor(){return this._state.shadowColor}set shadowColor(e){this._state.shadowColor=e}get shadowBlur(){return this._state.shadowBlur}set shadowBlur(e){e>=0&&isFinite(e)&&(this._state.shadowBlur=e)}get shadowOffsetX(){return this._state.shadowOffsetX}set shadowOffsetX(e){isFinite(e)&&(this._state.shadowOffsetX=e)}get shadowOffsetY(){return this._state.shadowOffsetY}set shadowOffsetY(e){isFinite(e)&&(this._state.shadowOffsetY=e)}get font(){return this._state.font}set font(e){this._state.font=e}get textAlign(){return this._state.textAlign}set textAlign(e){this._state.textAlign=e}get textBaseline(){return this._state.textBaseline}set textBaseline(e){this._state.textBaseline=e}get direction(){return this._state.direction}set direction(e){this._state.direction=e}_toDataURL(e,t){this._surface.flush();let n=imports.gi.Gio,r=imports.gi.GLib,[,i]=r.file_open_tmp(`canvas-XXXXXX.png`);try{this._surface.writeToPNG(i);let[,e]=n.File.new_for_path(i).load_contents(null);return`data:image/png;base64,${r.base64_encode(e)}`}finally{try{r.unlink(i)}catch{}}}_dispose(){this._ctx.$dispose(),this._surface.finish()}};s(CanvasRenderingContext2D.prototype);export{CanvasRenderingContext2D};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{asCairoPattern as e}from"../cairo-types.js";import{Path2D as t}from"../canvas-path.js";import{isCanvasImageSource as n,isPixbufImageSource as r}from"../dom-types.js";import i from"cairo";import a from"gi://Gdk?version=4.0";function getDrawImageSource(e){if(r(e)){let t=e._pixbuf;return{pixbuf:t,imgWidth:t.get_width(),imgHeight:t.get_height()}}if(n(e)){let t=e.width??0,n=e.height??0;if(!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0)return null;let r=e.getContext(`2d`);if(r&&typeof r._getSurface==`function`){let e=r._getSurface();e.flush();let i=a.pixbuf_get_from_surface(e,0,0,t,n);if(i)return{pixbuf:i,imgWidth:t,imgHeight:n}}}return null}const o={fill(e,n){this._ensureSurface(),this._applyCompositing(),this._applyFillStyle();let r;e instanceof t?(this._ctx.newPath(),e._replayOnCairo(this._ctx),r=n):r=e,this._ctx.setFillRule(r===`evenodd`?i.FillRule.EVEN_ODD:i.FillRule.WINDING),this._ctx.fillPreserve()},stroke(e){this._ensureSurface(),this._applyCompositing(),this._applyStrokeStyle(),this._applyLineStyle(),e instanceof t&&(this._ctx.newPath(),e._replayOnCairo(this._ctx)),this._ctx.strokePreserve()},fillRect(e,t,n,r){this._ensureSurface(),this._applyCompositing();let i=this._ctx.copyPath();this._hasShadow()&&this._renderShadow(()=>{this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill()}),this._applyFillStyle(),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill(),this._ctx.newPath(),this._ctx.appendPath(i)},strokeRect(e,t,n,r){this._ensureSurface(),this._applyCompositing();let i=this._ctx.copyPath();this._hasShadow()&&this._renderShadow(()=>{this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.stroke()}),this._applyStrokeStyle(),this._applyLineStyle(),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.stroke(),this._ctx.newPath(),this._ctx.appendPath(i)},clearRect(e,t,n,r){this._ensureSurface();let a=this._ctx.copyPath();this._ctx.save(),this._ctx.setOperator(i.Operator.CLEAR),this._ctx.newPath(),this._ctx.rectangle(e,t,n,r),this._ctx.fill(),this._ctx.restore(),this._ctx.newPath(),this._ctx.appendPath(a)},clip(e,n){this._ensureSurface();let r;e instanceof t?(this._ctx.newPath(),e._replayOnCairo(this._ctx),r=n):r=e,this._ctx.setFillRule(r===`evenodd`?i.FillRule.EVEN_ODD:i.FillRule.WINDING),this._ctx.clip()},isPointInPath(e,n,r,a){this._ensureSurface();let o,s,c;return e instanceof t?(this._ctx.newPath(),e._replayOnCairo(this._ctx),o=n,s=r,c=a):(o=e,s=n,c=r),this._ctx.setFillRule(c===`evenodd`?i.FillRule.EVEN_ODD:i.FillRule.WINDING),this._ctx.inFill(o,s)},isPointInStroke(e,n,r){return this._ensureSurface(),this._applyLineStyle(),e instanceof t?(this._ctx.newPath(),e._replayOnCairo(this._ctx),this._ctx.inStroke(n,r)):this._ctx.inStroke(e,n)},drawImage(t,n,r,o,s,c,l,u,d){this._ensureSurface(),this._applyCompositing();let f,p,m,h,g,_,v,y,b=getDrawImageSource(t);if(!b)return;let{pixbuf:x,imgWidth:S,imgHeight:C}=b;if(o===void 0?(f=0,p=0,m=S,h=C,g=n,_=r,v=S,y=C):c===void 0?(f=0,p=0,m=S,h=C,g=n,_=r,v=o,y=s):(f=n,p=r,m=o,h=s,g=c,_=l,v=u,y=d),!Number.isFinite(f)||!Number.isFinite(p)||!Number.isFinite(m)||!Number.isFinite(h)||!Number.isFinite(g)||!Number.isFinite(_)||!Number.isFinite(v)||!Number.isFinite(y)||m===0||h===0||v===0||y===0)return;this._ctx.save(),this._ctx.rectangle(g,_,v,y),this._ctx.clip(),this._ctx.translate(g,_),this._ctx.scale(v/m,y/h),this._ctx.translate(-f,-p),a.cairo_set_source_pixbuf(this._ctx,x,0,0);let w=e(this._ctx.getSource?.());if(w){let e;e=this._state.imageSmoothingEnabled?this._state.imageSmoothingQuality===`high`?i.Filter.BEST:i.Filter.BILINEAR:i.Filter.NEAREST,w.setFilter(e)}this._state.globalAlpha<1?this._ctx.paintWithAlpha(this._state.globalAlpha):this._ctx.paint(),this._ctx.restore()}};function installDrawingMethods(e){Object.assign(e,o)}export{installDrawingMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{CanvasGradient as e}from"../canvas-gradient.js";import{CanvasPattern as t}from"../canvas-pattern.js";const n={createLinearGradient(t,n,r,i){return new e(`linear`,t,n,r,i)},createRadialGradient(t,n,r,i,a,o){return new e(`radial`,t,n,i,a,r,o)},createPattern(e,n){return t.create(e,n)}};function installFactoryMethods(e){Object.assign(e,n)}export{installFactoryMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{installTransformMethods as e}from"./transforms.js";import{installPathMethods as t}from"./path-ops.js";import{installDrawingMethods as n}from"./drawing.js";import{installPixelMethods as r}from"./pixels.js";import{installTextMethods as i}from"./text-rendering.js";import{installFactoryMethods as a}from"./factories.js";function installAllContextMethods(o){e(o),t(o),n(o),r(o),i(o),a(o)}export{installAllContextMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{cairoArcTo as e,cairoEllipse as t,cairoRoundRect as n,quadraticToCubic as r}from"../cairo-utils.js";const i={beginPath(){this._ensureSurface(),this._ctx.newPath()},moveTo(e,t){this._ensureSurface(),this._ctx.moveTo(e,t)},lineTo(e,t){this._ensureSurface(),this._ctx.lineTo(e,t)},closePath(){this._ensureSurface(),this._ctx.closePath()},bezierCurveTo(e,t,n,r,i,a){this._ensureSurface(),this._ctx.curveTo(e,t,n,r,i,a)},quadraticCurveTo(e,t,n,i){this._ensureSurface();let a,o;this._ctx.hasCurrentPoint()?[a,o]=this._ctx.getCurrentPoint():(a=e,o=t);let{cp1x:s,cp1y:c,cp2x:l,cp2y:u}=r(a,o,e,t,n,i);this._ctx.curveTo(s,c,l,u,n,i)},arc(e,t,n,r,i,a=!1){if(this._ensureSurface(),Math.abs(i-r)>=2*Math.PI){this._ctx.arc(e,t,n,0,2*Math.PI);return}a?this._ctx.arcNegative(e,t,n,r,i):this._ctx.arc(e,t,n,r,i)},arcTo(t,n,r,i,a){this._ensureSurface();let o,s;this._ctx.hasCurrentPoint()?[o,s]=this._ctx.getCurrentPoint():(o=t,s=n,this._ctx.moveTo(t,n)),e(this._ctx,o,s,t,n,r,i,a)},ellipse(e,n,r,i,a,o,s,c=!1){if(this._ensureSurface(),r<0||i<0)throw RangeError(`The radii provided are negative`);t(this._ctx,e,n,r,i,a,o,s,c)},rect(e,t,n,r){this._ensureSurface(),this._ctx.rectangle(e,t,n,r)},roundRect(e,t,r,i,a=0){this._ensureSurface(),n(this._ctx,e,t,r,i,a)}};function installPathMethods(e){Object.assign(e,i)}export{installPathMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{OurImageData as e}from"../image-data.js";import t from"cairo";import n from"gi://Gdk?version=4.0";import r from"gi://GdkPixbuf";const i={createImageData(t,n){return typeof t==`number`?new e(Math.abs(t),Math.abs(n)):new e(t.width,t.height)},getImageData(t,r,i,a){this._ensureSurface(),this._surface.flush();let o=n.pixbuf_get_from_surface(this._surface,t,r,i,a);if(!o)return new e(i,a);let s=o.get_pixels(),c=o.get_has_alpha(),l=o.get_rowstride(),u=o.get_n_channels(),d=new Uint8ClampedArray(i*a*4);for(let e=0;e<a;e++)for(let t=0;t<i;t++){let n=e*l+t*u,r=(e*i+t)*4;d[r]=s[n],d[r+1]=s[n+1],d[r+2]=s[n+2],d[r+3]=c?s[n+3]:255}return new e(d,i,a)},putImageData(e,i,a,o,s,c,l){this._ensureSurface();let u=o??0,d=s??0,f=c??e.width,p=l??e.height,m=e.data,h=e.width,g=new Uint8Array(f*p*4);for(let e=0;e<p;e++)for(let t=0;t<f;t++){let n=((d+e)*h+(u+t))*4,r=(e*f+t)*4;g[r]=m[n],g[r+1]=m[n+1],g[r+2]=m[n+2],g[r+3]=m[n+3]}let _=r.Pixbuf.new_from_bytes(g,r.Colorspace.RGB,!0,8,f,p,f*4);this._ctx.save(),this._ctx.setOperator(t.Operator.SOURCE),n.cairo_set_source_pixbuf(this._ctx,_,i+u,a+d),this._ctx.rectangle(i+u,a+d,f,p),this._ctx.fill(),this._ctx.restore()}};function installPixelMethods(e){Object.assign(e,i)}export{installPixelMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{parseColor as e}from"../color.js";import t from"cairo";import n from"gi://Pango";import r from"gi://PangoCairo";function parseFontToDescription(e){let t=e.match(/^\s*(italic|oblique|normal)?\s*(small-caps|normal)?\s*(bold|bolder|lighter|[1-9]00|normal)?\s*(\d+(?:\.\d+)?)(px|pt|em|rem|%)?\s*(?:\/\S+)?\s*(.+)?$/i);if(!t)return n.font_description_from_string(e);let r=t[1]||``,i=t[3]||``,a=parseFloat(t[4])||10,o=(t[5]||`px`).toLowerCase(),s=(t[6]||`sans-serif`).replace(/['"]/g,``).trim();o===`pt`?a=a*96/72:o===`em`||o===`rem`?a*=16:o===`%`&&(a=a/100*16);let c=s;r===`italic`?c+=` Italic`:r===`oblique`&&(c+=` Oblique`),i===`bold`||i===`bolder`||parseInt(i)>=600?c+=` Bold`:(i===`lighter`||parseInt(i)>0&&parseInt(i)<=300)&&(c+=` Light`);let l=n.font_description_from_string(c);return l.set_absolute_size(a*n.SCALE),l}function createTextLayout(e,t){let i=r.create_layout(e._ctx);i.set_text(t,-1),i.get_context().set_base_dir(n.Direction.LTR),i.context_changed();let a=parseFontToDescription(e._state.font);return i.set_font_description(a),i}function getTextAlignOffset(e,t){let[,n]=t.get_pixel_extents(),r=n.width;switch(e._state.textAlign){case`center`:return-r/2;case`right`:case`end`:return-r;default:return 0}}function getTextBaselineOffset(e,t){let r=t.get_font_description()||parseFontToDescription(e._state.font),i=t.get_context().get_metrics(r,null),a=i.get_ascent()/n.SCALE,o=i.get_descent()/n.SCALE,s=a+o;switch(e._state.textBaseline){case`top`:return 0;case`hanging`:return-(a*.2);case`middle`:return-(s/2);case`alphabetic`:return-a;case`ideographic`:return-(a+o*.5);case`bottom`:return-s;default:return-a}}const i={fillText(n,i,a,o){this._ensureSurface(),this._applyCompositing();let s=createTextLayout(this,n),c=getTextAlignOffset(this,s),l=getTextBaselineOffset(this,s);if(this._hasShadow()){let n=e(this._state.shadowColor);if(n){let[e,o]=this._deviceToUserDistance(this._state.shadowOffsetX,this._state.shadowOffsetY),u=this._state.shadowBlur,d;if(u>0){let[t]=this._deviceToUserDistance(u,0),[,r]=this._deviceToUserDistance(0,u);d=[[e,o,n.a],[e+t,o,n.a*.5],[e-t,o,n.a*.5],[e,o+r,n.a*.5],[e,o-r,n.a*.5]]}else d=[[e,o,n.a]];let f=this._state.imageSmoothingEnabled?t.Antialias.DEFAULT:t.Antialias.NONE;for(let[e,t,o]of d)this._ctx.save(),this._ctx.setAntialias(f),this._ctx.setSourceRGBA(n.r,n.g,n.b,o),this._ctx.moveTo(i+c+e,a+l+t),r.show_layout(this._ctx,s),this._ctx.restore()}}this._applyFillStyle(),this._ctx.save(),this._ctx.setAntialias(this._state.imageSmoothingEnabled?t.Antialias.DEFAULT:t.Antialias.NONE),this._ctx.moveTo(i+c,a+l),r.show_layout(this._ctx,s),this._ctx.restore()},strokeText(e,n,i,a){this._ensureSurface(),this._applyCompositing(),this._applyStrokeStyle(),this._applyLineStyle();let o=createTextLayout(this,e),s=getTextAlignOffset(this,o),c=getTextBaselineOffset(this,o);this._ctx.save(),this._ctx.setAntialias(this._state.imageSmoothingEnabled?t.Antialias.DEFAULT:t.Antialias.NONE),this._ctx.moveTo(n+s,i+c),r.layout_path(this._ctx,o),this._ctx.stroke(),this._ctx.restore()},measureText(e){this._ensureSurface();let t=createTextLayout(this,e),[r,i]=t.get_pixel_extents(),a=t.get_baseline()/n.SCALE,o=Math.max(0,a-r.y),s=Math.max(0,r.y+r.height-a),c=t.get_font_description()||parseFontToDescription(this._state.font),l=t.get_context().get_metrics(c,null),u=l.get_ascent()/n.SCALE,d=l.get_descent()/n.SCALE;return{width:i.width,actualBoundingBoxAscent:o,actualBoundingBoxDescent:s,actualBoundingBoxLeft:Math.max(0,-r.x),actualBoundingBoxRight:r.x+r.width,fontBoundingBoxAscent:u,fontBoundingBoxDescent:d,alphabeticBaseline:0,emHeightAscent:u,emHeightDescent:d,hangingBaseline:u*.8,ideographicBaseline:-d}}};function installTextMethods(e){Object.assign(e,i)}export{installTextMethods};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";const e={translate(e,t){this._ensureSurface(),this._ctx.translate(e,t)},rotate(e){this._ensureSurface(),this._ctx.rotate(e)},scale(e,t){this._ensureSurface(),this._ctx.scale(e,t)},transform(e,t,n,r,i,a){if(this._ensureSurface(),!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||!Number.isFinite(a))return;let o=i,s=a,c=Math.hypot(e,t),l=Math.hypot(n,r),u=Math.atan2(t,e);this._ctx.translate(o,s),u!==0&&this._ctx.rotate(u),(c!==1||l!==1)&&this._ctx.scale(c,l)},setTransform(e,t,n,r,i,a){if(this._ensureSurface(),typeof e==`object`&&e){let t=e;this._ctx.identityMatrix(),this.transform(t.a??t.m11??1,t.b??t.m12??0,t.c??t.m21??0,t.d??t.m22??1,t.e??t.m41??0,t.f??t.m42??0)}else typeof e==`number`?(this._ctx.identityMatrix(),this.transform(e,t,n,r,i,a)):this._ctx.identityMatrix()},getTransform(){let e=this._ctx.userToDevice(0,0),t=this._ctx.userToDevice(1,0),n=this._ctx.userToDevice(0,1),r=e[0]??0,i=e[1]??0,a=(t[0]??0)-r,o=(t[1]??0)-i,s=(n[0]??0)-r,c=(n[1]??0)-i,l=globalThis.DOMMatrix;return typeof l==`function`?new l([a,o,s,c,r,i]):{a,b:o,c:s,d:c,e:r,f:i,m11:a,m12:o,m13:0,m14:0,m21:s,m22:c,m23:0,m24:0,m31:0,m32:0,m33:1,m34:0,m41:r,m42:i,m43:0,m44:1,is2D:!0,isIdentity:a===1&&o===0&&s===0&&c===1&&r===0&&i===0}},resetTransform(){this._ensureSurface(),this._ctx.identityMatrix()}};function installTransformMethods(t){Object.assign(t,e)}export{installTransformMethods};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Cairo from 'cairo';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import './context/index.js';
|
|
3
|
+
import type { CanvasLike } from './dom-types.js';
|
|
4
|
+
import { type CanvasState } from './canvas-state.js';
|
|
4
5
|
/**
|
|
5
6
|
* Options bag passed through the `getContext('2d', options)` factory. Mirrors
|
|
6
7
|
* the WHATWG `CanvasRenderingContext2DSettings` dictionary; fields are
|
|
@@ -18,36 +19,36 @@ export interface CanvasRenderingContext2DInit {
|
|
|
18
19
|
*/
|
|
19
20
|
export declare class CanvasRenderingContext2D {
|
|
20
21
|
readonly canvas: CanvasLike;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
_surface: Cairo.ImageSurface;
|
|
23
|
+
_ctx: Cairo.Context;
|
|
24
|
+
_state: CanvasState;
|
|
25
|
+
_stateStack: CanvasState[];
|
|
26
|
+
_surfaceWidth: number;
|
|
27
|
+
_surfaceHeight: number;
|
|
27
28
|
constructor(canvas: CanvasLike, _options?: CanvasRenderingContext2DInit);
|
|
28
29
|
/** Ensure the surface matches the current canvas dimensions. Recreate if resized. */
|
|
29
|
-
|
|
30
|
+
_ensureSurface(): void;
|
|
30
31
|
/** Reset drawing state to defaults (called when canvas dimensions are explicitly reset). */
|
|
31
32
|
_resetState(): void;
|
|
32
33
|
/** Apply the current fill style (color, gradient, or pattern) to the Cairo context. */
|
|
33
|
-
|
|
34
|
+
_applyFillStyle(): void;
|
|
34
35
|
/** Apply the current stroke style to the Cairo context. */
|
|
35
|
-
|
|
36
|
+
_applyStrokeStyle(): void;
|
|
36
37
|
/**
|
|
37
38
|
* Apply the current imageSmoothingEnabled + imageSmoothingQuality state
|
|
38
39
|
* to the currently installed Cairo source pattern. Per Canvas 2D spec,
|
|
39
40
|
* the filter is read from the context at *draw* time, not at pattern
|
|
40
41
|
* creation — so we re-apply it on every fill/stroke.
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
+
_applyPatternFilter(): void;
|
|
43
44
|
/** Apply line properties to the Cairo context. */
|
|
44
|
-
|
|
45
|
+
_applyLineStyle(): void;
|
|
45
46
|
/** Apply compositing operator. */
|
|
46
|
-
|
|
47
|
+
_applyCompositing(): void;
|
|
47
48
|
/** Get the Cairo ImageSurface (used by other contexts like drawImage). */
|
|
48
49
|
_getSurface(): Cairo.ImageSurface;
|
|
49
50
|
/** Check if shadow rendering is needed. */
|
|
50
|
-
|
|
51
|
+
_hasShadow(): boolean;
|
|
51
52
|
/**
|
|
52
53
|
* Convert a distance from device pixels to Cairo user space by inverting
|
|
53
54
|
* the linear part of the current CTM (translation doesn't affect distances).
|
|
@@ -57,7 +58,7 @@ export declare class CanvasRenderingContext2D {
|
|
|
57
58
|
* that `ctx.moveTo(x + sdx, y + sdy)` produces the correct pixel offset
|
|
58
59
|
* regardless of any ctx.scale() or ctx.rotate() in effect.
|
|
59
60
|
*/
|
|
60
|
-
|
|
61
|
+
_deviceToUserDistance(dx: number, dy: number): [number, number];
|
|
61
62
|
/**
|
|
62
63
|
* Shadow rendering is intentionally a no-op.
|
|
63
64
|
*
|
|
@@ -73,29 +74,9 @@ export declare class CanvasRenderingContext2D {
|
|
|
73
74
|
* affect the showcase. A correct implementation is tracked as a
|
|
74
75
|
* separate Canvas 2D Phase-5 enhancement.
|
|
75
76
|
*/
|
|
76
|
-
|
|
77
|
+
_renderShadow(_drawOp: () => void): void;
|
|
77
78
|
save(): void;
|
|
78
79
|
restore(): void;
|
|
79
|
-
translate(x: number, y: number): void;
|
|
80
|
-
rotate(angle: number): void;
|
|
81
|
-
scale(x: number, y: number): void;
|
|
82
|
-
/**
|
|
83
|
-
* Multiply the current transformation matrix by the given values.
|
|
84
|
-
* Matrix: [a c e]
|
|
85
|
-
* [b d f]
|
|
86
|
-
* [0 0 1]
|
|
87
|
-
*/
|
|
88
|
-
transform(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
89
|
-
/**
|
|
90
|
-
* Reset the transform to identity, then apply the given matrix.
|
|
91
|
-
*/
|
|
92
|
-
setTransform(matrix?: DOMMatrix2DInit): void;
|
|
93
|
-
setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
94
|
-
/**
|
|
95
|
-
* Return the current transformation matrix as a DOMMatrix-like object.
|
|
96
|
-
*/
|
|
97
|
-
getTransform(): DOMMatrix;
|
|
98
|
-
resetTransform(): void;
|
|
99
80
|
get fillStyle(): string | CanvasGradient | CanvasPattern;
|
|
100
81
|
set fillStyle(value: string | CanvasGradient | CanvasPattern);
|
|
101
82
|
get strokeStyle(): string | CanvasGradient | CanvasPattern;
|
|
@@ -136,63 +117,6 @@ export declare class CanvasRenderingContext2D {
|
|
|
136
117
|
set textBaseline(value: CanvasTextBaseline);
|
|
137
118
|
get direction(): CanvasDirection;
|
|
138
119
|
set direction(value: CanvasDirection);
|
|
139
|
-
beginPath(): void;
|
|
140
|
-
moveTo(x: number, y: number): void;
|
|
141
|
-
lineTo(x: number, y: number): void;
|
|
142
|
-
closePath(): void;
|
|
143
|
-
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
144
|
-
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
145
|
-
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
146
|
-
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
147
|
-
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
148
|
-
rect(x: number, y: number, w: number, h: number): void;
|
|
149
|
-
roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void;
|
|
150
|
-
fill(fillRule?: CanvasFillRule): void;
|
|
151
|
-
fill(path: Path2D, fillRule?: CanvasFillRule): void;
|
|
152
|
-
stroke(): void;
|
|
153
|
-
stroke(path: Path2D): void;
|
|
154
|
-
fillRect(x: number, y: number, w: number, h: number): void;
|
|
155
|
-
strokeRect(x: number, y: number, w: number, h: number): void;
|
|
156
|
-
clearRect(x: number, y: number, w: number, h: number): void;
|
|
157
|
-
clip(fillRule?: CanvasFillRule): void;
|
|
158
|
-
clip(path: Path2D, fillRule?: CanvasFillRule): void;
|
|
159
|
-
isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
|
160
|
-
isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
|
161
|
-
isPointInStroke(x: number, y: number): boolean;
|
|
162
|
-
isPointInStroke(path: Path2D, x: number, y: number): boolean;
|
|
163
|
-
createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
|
|
164
|
-
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
|
|
165
|
-
createPattern(image: unknown, repetition: string | null): CanvasPattern | null;
|
|
166
|
-
createImageData(sw: number, sh: number): ImageData;
|
|
167
|
-
createImageData(imagedata: ImageData): ImageData;
|
|
168
|
-
getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
|
|
169
|
-
putImageData(imageData: ImageData, dx: number, dy: number, dirtyX?: number, dirtyY?: number, dirtyWidth?: number, dirtyHeight?: number): void;
|
|
170
|
-
drawImage(image: unknown, dx: number, dy: number): void;
|
|
171
|
-
drawImage(image: unknown, dx: number, dy: number, dw: number, dh: number): void;
|
|
172
|
-
drawImage(image: unknown, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
|
|
173
|
-
private _getDrawImageSource;
|
|
174
|
-
/** Create a PangoCairo layout configured with current font/text settings. */
|
|
175
|
-
private _createTextLayout;
|
|
176
|
-
/** Parse a CSS font string (e.g. "bold 16px Arial") into a Pango.FontDescription. */
|
|
177
|
-
private _parseFontToDescription;
|
|
178
|
-
/**
|
|
179
|
-
* Compute the x-offset for text alignment relative to the given x coordinate.
|
|
180
|
-
*/
|
|
181
|
-
private _getTextAlignOffset;
|
|
182
|
-
/**
|
|
183
|
-
* Compute the y-offset for text baseline positioning.
|
|
184
|
-
*
|
|
185
|
-
* PangoCairo.show_layout() places the layout TOP-LEFT at the current Cairo point
|
|
186
|
-
* (not the baseline). Within the layout, the first line's baseline is at
|
|
187
|
-
* approximately `ascent` pixels below the layout top.
|
|
188
|
-
*
|
|
189
|
-
* For CSS textBaseline semantics, we shift the current point UP (negative offset)
|
|
190
|
-
* so the layout top lands at the right position relative to the user's y coordinate.
|
|
191
|
-
*/
|
|
192
|
-
private _getTextBaselineOffset;
|
|
193
|
-
fillText(text: string, x: number, y: number, _maxWidth?: number): void;
|
|
194
|
-
strokeText(text: string, x: number, y: number, _maxWidth?: number): void;
|
|
195
|
-
measureText(text: string): TextMetrics;
|
|
196
120
|
/**
|
|
197
121
|
* Write the canvas surface to a PNG file and return as data URL.
|
|
198
122
|
* Used by HTMLCanvasElement.toDataURL() when a '2d' context is active.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Path2D } from '../canvas-path.js';
|
|
2
|
+
export interface DrawingMethods {
|
|
3
|
+
fill(fillRule?: CanvasFillRule): void;
|
|
4
|
+
fill(path: Path2D, fillRule?: CanvasFillRule): void;
|
|
5
|
+
stroke(): void;
|
|
6
|
+
stroke(path: Path2D): void;
|
|
7
|
+
fillRect(x: number, y: number, w: number, h: number): void;
|
|
8
|
+
strokeRect(x: number, y: number, w: number, h: number): void;
|
|
9
|
+
clearRect(x: number, y: number, w: number, h: number): void;
|
|
10
|
+
clip(fillRule?: CanvasFillRule): void;
|
|
11
|
+
clip(path: Path2D, fillRule?: CanvasFillRule): void;
|
|
12
|
+
isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
|
13
|
+
isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;
|
|
14
|
+
isPointInStroke(x: number, y: number): boolean;
|
|
15
|
+
isPointInStroke(path: Path2D, x: number, y: number): boolean;
|
|
16
|
+
drawImage(image: unknown, dx: number, dy: number): void;
|
|
17
|
+
drawImage(image: unknown, dx: number, dy: number, dw: number, dh: number): void;
|
|
18
|
+
drawImage(image: unknown, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
|
|
19
|
+
}
|
|
20
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
21
|
+
interface CanvasRenderingContext2D extends DrawingMethods {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Install drawing methods on CanvasRenderingContext2D.prototype. */
|
|
25
|
+
export declare function installDrawingMethods(proto: object): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface FactoryMethods {
|
|
2
|
+
createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
|
|
3
|
+
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
|
|
4
|
+
createPattern(image: unknown, repetition: string | null): CanvasPattern | null;
|
|
5
|
+
}
|
|
6
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
7
|
+
interface CanvasRenderingContext2D extends FactoryMethods {
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Install gradient / pattern factory methods on CanvasRenderingContext2D.prototype. */
|
|
11
|
+
export declare function installFactoryMethods(proto: object): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { TransformMethods } from './transforms.js';
|
|
2
|
+
export type { PathMethods } from './path-ops.js';
|
|
3
|
+
export type { DrawingMethods } from './drawing.js';
|
|
4
|
+
export type { PixelMethods } from './pixels.js';
|
|
5
|
+
export type { TextMethods } from './text-rendering.js';
|
|
6
|
+
export type { FactoryMethods } from './factories.js';
|
|
7
|
+
export declare function installAllContextMethods(proto: object): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface PathMethods {
|
|
2
|
+
beginPath(): void;
|
|
3
|
+
moveTo(x: number, y: number): void;
|
|
4
|
+
lineTo(x: number, y: number): void;
|
|
5
|
+
closePath(): void;
|
|
6
|
+
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
|
|
7
|
+
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
|
|
8
|
+
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
9
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
|
|
10
|
+
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
|
|
11
|
+
rect(x: number, y: number, w: number, h: number): void;
|
|
12
|
+
roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void;
|
|
13
|
+
}
|
|
14
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
15
|
+
interface CanvasRenderingContext2D extends PathMethods {
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Install path-construction methods on CanvasRenderingContext2D.prototype. */
|
|
19
|
+
export declare function installPathMethods(proto: object): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface PixelMethods {
|
|
2
|
+
createImageData(sw: number, sh: number): ImageData;
|
|
3
|
+
createImageData(imagedata: ImageData): ImageData;
|
|
4
|
+
getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
|
|
5
|
+
putImageData(imageData: ImageData, dx: number, dy: number, dirtyX?: number, dirtyY?: number, dirtyWidth?: number, dirtyHeight?: number): void;
|
|
6
|
+
}
|
|
7
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
8
|
+
interface CanvasRenderingContext2D extends PixelMethods {
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Install pixel-ops (ImageData) methods on CanvasRenderingContext2D.prototype. */
|
|
12
|
+
export declare function installPixelMethods(proto: object): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TextMethods {
|
|
2
|
+
fillText(text: string, x: number, y: number, maxWidth?: number): void;
|
|
3
|
+
strokeText(text: string, x: number, y: number, maxWidth?: number): void;
|
|
4
|
+
measureText(text: string): TextMetrics;
|
|
5
|
+
}
|
|
6
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
7
|
+
interface CanvasRenderingContext2D extends TextMethods {
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Install text-rendering methods on CanvasRenderingContext2D.prototype. */
|
|
11
|
+
export declare function installTextMethods(proto: object): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface TransformMethods {
|
|
2
|
+
translate(x: number, y: number): void;
|
|
3
|
+
rotate(angle: number): void;
|
|
4
|
+
scale(x: number, y: number): void;
|
|
5
|
+
transform(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
6
|
+
setTransform(matrix?: DOMMatrix2DInit): void;
|
|
7
|
+
setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
8
|
+
getTransform(): DOMMatrix;
|
|
9
|
+
resetTransform(): void;
|
|
10
|
+
}
|
|
11
|
+
declare module '../canvas-rendering-context-2d.js' {
|
|
12
|
+
interface CanvasRenderingContext2D extends TransformMethods {
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Install transform methods on CanvasRenderingContext2D.prototype. */
|
|
16
|
+
export declare function installTransformMethods(proto: object): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/canvas2d-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.22",
|
|
4
4
|
"description": "Cairo-backed Canvas 2D core (CanvasRenderingContext2D, Path2D, ImageData) — no GTK dependency",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
"offscreen"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@girs/gdk-4.0": "4.0.0-4.0.
|
|
38
|
-
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.
|
|
39
|
-
"@girs/gjs": "4.0.
|
|
40
|
-
"@girs/glib-2.0": "2.88.0-4.0.
|
|
41
|
-
"@girs/gobject-2.0": "2.88.0-4.0.
|
|
42
|
-
"@girs/pango-1.0": "1.57.1-4.0.
|
|
43
|
-
"@girs/pangocairo-1.0": "1.0.0-4.0.
|
|
37
|
+
"@girs/gdk-4.0": "4.0.0-4.0.1",
|
|
38
|
+
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.1",
|
|
39
|
+
"@girs/gjs": "4.0.1",
|
|
40
|
+
"@girs/glib-2.0": "2.88.0-4.0.1",
|
|
41
|
+
"@girs/gobject-2.0": "2.88.0-4.0.1",
|
|
42
|
+
"@girs/pango-1.0": "1.57.1-4.0.1",
|
|
43
|
+
"@girs/pangocairo-1.0": "1.0.0-4.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@gjsify/cli": "^0.4.
|
|
47
|
-
"@gjsify/dom-elements": "^0.4.
|
|
48
|
-
"@gjsify/unit": "^0.4.
|
|
49
|
-
"@types/node": "^25.
|
|
46
|
+
"@gjsify/cli": "^0.4.22",
|
|
47
|
+
"@gjsify/dom-elements": "^0.4.22",
|
|
48
|
+
"@gjsify/unit": "^0.4.22",
|
|
49
|
+
"@types/node": "^25.9.1",
|
|
50
50
|
"typescript": "^6.0.3"
|
|
51
51
|
}
|
|
52
52
|
}
|