| 1 |
module htmlayout.graphin; |
|---|
| 2 |
|
|---|
| 3 |
import htmlayout.capi; |
|---|
| 4 |
import tango.sys.win32.Types; |
|---|
| 5 |
import tango.stdc.stringz; |
|---|
| 6 |
import tango.text.convert.Utf; |
|---|
| 7 |
import tango.io.model.IConduit; |
|---|
| 8 |
import tango.io.device.File; |
|---|
| 9 |
import htmlayout.htmlayout; //bug, not import this |
|---|
| 10 |
class HImage |
|---|
| 11 |
{ |
|---|
| 12 |
protected this(HIMG h,UINT sizex,UINT sizey) |
|---|
| 13 |
{ |
|---|
| 14 |
mHandle=h; |
|---|
| 15 |
mWidth=sizex; |
|---|
| 16 |
mHeight=sizey; |
|---|
| 17 |
} |
|---|
| 18 |
|
|---|
| 19 |
~this() |
|---|
| 20 |
{ |
|---|
| 21 |
if(mHandle) mGraphin.imageRelease(mHandle); |
|---|
| 22 |
} |
|---|
| 23 |
|
|---|
| 24 |
static HImage opCall(UINT sizex,UINT sizey) |
|---|
| 25 |
{ |
|---|
| 26 |
if(mGraphin is null) mGraphin=gApi(); |
|---|
| 27 |
HIMG himg; |
|---|
| 28 |
if(mGraphin.imageCreate(sizex,sizey,&himg)==GRAPHIN_OK && himg) return new HImage(himg,sizex,sizey); |
|---|
| 29 |
else return null; |
|---|
| 30 |
} |
|---|
| 31 |
|
|---|
| 32 |
static HImage opCall(char[] data) // loads image from png or jpeg enoded data |
|---|
| 33 |
{ |
|---|
| 34 |
if(mGraphin is null) mGraphin=gApi(); |
|---|
| 35 |
HIMG himg; |
|---|
| 36 |
if(mGraphin.imageLoad(cast(ubyte*)data.ptr,data.length,&himg)==GRAPHIN_OK && himg) |
|---|
| 37 |
{ |
|---|
| 38 |
BYTE* ddata;UINT width;UINT height;INT stride;UINT pixel_format; |
|---|
| 39 |
mGraphin.imageGetInfo(himg,&ddata,&width,&height,&stride,&pixel_format); |
|---|
| 40 |
return new HImage(himg,width,height); |
|---|
| 41 |
} |
|---|
| 42 |
else return null; |
|---|
| 43 |
} |
|---|
| 44 |
|
|---|
| 45 |
bool save(OutputStream strm,uint quality = 0 /*JPEG qquality: 20..100,if 0 - PNG */) // save image as png or jpeg enoded data |
|---|
| 46 |
{ |
|---|
| 47 |
static uint lastsaver=0; |
|---|
| 48 |
auto id=++lastsaver; |
|---|
| 49 |
mSavers[id]=strm; |
|---|
| 50 |
scope(exit) mSavers.remove(id); |
|---|
| 51 |
if(quality >= 1 && quality <= 100) // jpeg |
|---|
| 52 |
return (lastResult = mGraphin.imageSave(mHandle,&mWriteImage,cast(void*)id,24,1,quality))==GRAPHIN_OK; |
|---|
| 53 |
else // png |
|---|
| 54 |
return (lastResult = mGraphin.imageSave(mHandle,&mWriteImage,cast(void*)id,32,0,0))==GRAPHIN_OK; |
|---|
| 55 |
} |
|---|
| 56 |
|
|---|
| 57 |
bool save(char[] file,uint quality=0) |
|---|
| 58 |
{ |
|---|
| 59 |
File f; |
|---|
| 60 |
try |
|---|
| 61 |
f=new File(file,File.WriteCreate); |
|---|
| 62 |
catch(Object o) |
|---|
| 63 |
return false; |
|---|
| 64 |
scope(exit) f.close; |
|---|
| 65 |
return save(f,quality); |
|---|
| 66 |
} |
|---|
| 67 |
|
|---|
| 68 |
uint width() {return mWidth;} |
|---|
| 69 |
uint height() {return mHeight;} |
|---|
| 70 |
HIMG handle() {return mHandle;} |
|---|
| 71 |
|
|---|
| 72 |
bool clear(){return (lastResult=mGraphin.imageClear(mHandle))==GRAPHIN_OK;} |
|---|
| 73 |
|
|---|
| 74 |
// bitblit it to the hdc |
|---|
| 75 |
bool blit(HPLATFORMGFX hdc,INT dx,INT dy,INT sx=0,INT sy=0,INT w=-1,INT h=-1,bool blend=true){return (lastResult=mGraphin.imageBlit(hdc,dx,dy,mHandle,sx,sy,w<0?mWidth:w,h<0?mHeight:h,blend?1:0))==GRAPHIN_OK;} |
|---|
| 76 |
|
|---|
| 77 |
bool renderElement(htmlayout.element.HElement e,int x,int y,bool now=true){return (lastResult=HTMLayoutRenderElement(mHandle,POINT(x,y),e.handle,now?1:0))==GRAPHIN_OK;} |
|---|
| 78 |
|
|---|
| 79 |
GRAPHIN_RESULT lastResult; |
|---|
| 80 |
char[] lastResultMsg() {return graphinResultMsg(lastResult);} |
|---|
| 81 |
|
|---|
| 82 |
protected: |
|---|
| 83 |
HIMG mHandle; |
|---|
| 84 |
UINT mWidth; |
|---|
| 85 |
UINT mHeight; |
|---|
| 86 |
static Graphin *mGraphin; |
|---|
| 87 |
|
|---|
| 88 |
static tango.io.model.IConduit.OutputStream[uint] mSavers; |
|---|
| 89 |
|
|---|
| 90 |
extern(Windows) static BOOL mWriteImage(LPVOID prm, LPBYTE data, UINT data_length) |
|---|
| 91 |
{ |
|---|
| 92 |
auto saver=cast(uint)prm in mSavers; |
|---|
| 93 |
if(saver && *saver) return saver.write(data[0..data_length])==data_length; |
|---|
| 94 |
else return false; |
|---|
| 95 |
} |
|---|
| 96 |
} |
|---|
| 97 |
|
|---|
| 98 |
class HGraphics |
|---|
| 99 |
{ |
|---|
| 100 |
HGFX handle() {return mHandle;} |
|---|
| 101 |
|
|---|
| 102 |
this(HImage img) |
|---|
| 103 |
{ |
|---|
| 104 |
if(!img || !img.handle) throw new Exception("Bad image handle!"); |
|---|
| 105 |
if(mGraphin is null) mGraphin=gApi(); |
|---|
| 106 |
mGraphin.gCreate(img.handle,&mHandle); |
|---|
| 107 |
} |
|---|
| 108 |
~this() {if(mHandle) mGraphin.gRelease(mHandle);} |
|---|
| 109 |
|
|---|
| 110 |
static HGraphics opCall(HImage img) |
|---|
| 111 |
{ |
|---|
| 112 |
if(img && img.handle) return new HGraphics(img); |
|---|
| 113 |
else return null; |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
// Draws line from x1,y1 to x2,y2 using current line_color and line_gradient. |
|---|
| 117 |
bool line(POS x1,POS y1,POS x2,POS y2){return (lastResult=mGraphin.gLine(mHandle,x1,y1,x2,y2))==GRAPHIN_OK;} |
|---|
| 118 |
|
|---|
| 119 |
// Draws triangle using current lineColor/lineGradient and fillColor/fillGradient. |
|---|
| 120 |
bool triangle(POS x1,POS y1,POS x2,POS y2,POS x3,POS y3){return (lastResult=mGraphin.gTriangle(mHandle,x1,y1,x2,y2,x3,y3))==GRAPHIN_OK;} |
|---|
| 121 |
|
|---|
| 122 |
// Draws rectangle using current lineColor/lineGradient and fillColor/fillGradient |
|---|
| 123 |
bool rectangle(POS x1,POS y1,POS x2,POS y2){return (lastResult=mGraphin.gRectangle(mHandle,x1,y1,x2,y2))==GRAPHIN_OK;} |
|---|
| 124 |
|
|---|
| 125 |
// Draws rounded rectangle using current lineColor/lineGradient and fillColor/fillGradient with rounded corners. |
|---|
| 126 |
bool rectangle(POS x1,POS y1,POS x2,POS y2,DIM rAll) |
|---|
| 127 |
{ |
|---|
| 128 |
scope DIM[8] rad = [rAll,rAll,rAll,rAll,rAll,rAll,rAll,rAll]; |
|---|
| 129 |
return (lastResult=mGraphin.gRoundedRectangle(mHandle,x1,y1,x2,y2,rad.ptr))==GRAPHIN_OK; |
|---|
| 130 |
} |
|---|
| 131 |
|
|---|
| 132 |
bool rectangle(POS x1,POS y1,POS x2,POS y2,DIM rTopLeft,DIM rTopRight,DIM rBottomRight,DIM rBottomLeft) |
|---|
| 133 |
{ |
|---|
| 134 |
scope DIM[8] rad = [rTopLeft,rTopLeft,rTopRight,rTopRight,rBottomRight,rBottomRight,rBottomLeft,rBottomLeft]; |
|---|
| 135 |
return (lastResult=mGraphin.gRoundedRectangle(mHandle,x1,y1,x2,y2,rad.ptr))==GRAPHIN_OK; |
|---|
| 136 |
} |
|---|
| 137 |
|
|---|
| 138 |
|
|---|
| 139 |
// Draws circle or ellipse using current lineColor/lineGradient and fillColor/fillGradient. |
|---|
| 140 |
bool ellipse(POS x,POS y,POS rx,POS ry){return (lastResult=mGraphin.gEllipse(mHandle,x,y,rx,ry))==GRAPHIN_OK;} |
|---|
| 141 |
bool circle(POS x,POS y,POS radii){return (lastResult=mGraphin.gEllipse(mHandle,x,y,radii,radii))==GRAPHIN_OK;} |
|---|
| 142 |
|
|---|
| 143 |
// Draws closed arc using current lineColor/lineGradient and fillColor/fillGradient. |
|---|
| 144 |
bool arc(POS x,POS y,POS rx,POS ry,ANGLE start,ANGLE sweep){return (lastResult=mGraphin.gArc(mHandle,x,y,rx,ry,start,sweep))==GRAPHIN_OK;} |
|---|
| 145 |
|
|---|
| 146 |
// Draws star. |
|---|
| 147 |
bool star(POS x,POS y,POS r1,POS r2,ANGLE start,UINT rays){return (lastResult=mGraphin.gStar(mHandle,x,y,r1,r2,start,rays))==GRAPHIN_OK;} |
|---|
| 148 |
|
|---|
| 149 |
// Draws closed polygon using current lineColor/lineGradient and fillColor/fillGradient. |
|---|
| 150 |
bool polygon(POS* xy,UINT num_points){return (lastResult=mGraphin.gPolygon(mHandle,xy,num_points))==GRAPHIN_OK;} |
|---|
| 151 |
|
|---|
| 152 |
// you bet |
|---|
| 153 |
bool polyline(POS* xy,uint num_points){return (lastResult=mGraphin.gPolyline(mHandle,xy,num_points))==GRAPHIN_OK;} |
|---|
| 154 |
|
|---|
| 155 |
// SECTION: Path operations |
|---|
| 156 |
|
|---|
| 157 |
bool openPath(){return (lastResult=mGraphin.gOpenPath(mHandle))==GRAPHIN_OK;} |
|---|
| 158 |
|
|---|
| 159 |
bool moveTo(POS x,POS y,bool relative){return (lastResult=mGraphin.gMoveTo(mHandle,x,y,relative))==GRAPHIN_OK;} |
|---|
| 160 |
|
|---|
| 161 |
bool lineTo(POS x,POS y,bool relative){return (lastResult=mGraphin.gLineTo(mHandle,x,y,relative))==GRAPHIN_OK;} |
|---|
| 162 |
|
|---|
| 163 |
bool hlineTo(POS x,bool relative){return (lastResult=mGraphin.gHLineTo(mHandle,x,relative))==GRAPHIN_OK;} |
|---|
| 164 |
|
|---|
| 165 |
bool vlineTo(POS y,bool relative){return (lastResult=mGraphin.gVLineTo(mHandle,y,relative))==GRAPHIN_OK;} |
|---|
| 166 |
|
|---|
| 167 |
bool arcTo(POS x,POS y,ANGLE angle,POS rx,POS ry,bool is_large_arc,bool sweep_flag,bool relative){return (lastResult=mGraphin.gArcTo(mHandle,x,y,angle,rx,ry,is_large_arc,sweep_flag,relative))==GRAPHIN_OK;} |
|---|
| 168 |
|
|---|
| 169 |
bool ellipseTo(POS x,POS y,POS rx,POS ry,bool clockwise){return (lastResult=mGraphin.gEllipseTo(mHandle,x,y,rx,ry,clockwise))==GRAPHIN_OK;} |
|---|
| 170 |
|
|---|
| 171 |
bool quadraticCurveTo(POS xc,POS yc,POS x,POS y,bool relative){return (lastResult=mGraphin.gQuadraticCurveTo(mHandle,xc,yc,x,y,relative))==GRAPHIN_OK;} |
|---|
| 172 |
|
|---|
| 173 |
bool bezierCurveTo(POS xc1,POS yc1,POS xc2,POS yc2,POS x,POS y,bool relative){return (lastResult=mGraphin.gBezierCurveTo(mHandle,xc1,yc1,xc2,yc2,x,y,relative))==GRAPHIN_OK;} |
|---|
| 174 |
|
|---|
| 175 |
bool closePath(){return (lastResult=mGraphin.gClosePath(mHandle))==GRAPHIN_OK;} |
|---|
| 176 |
|
|---|
| 177 |
bool drawPath(DRAW_PATH_MODE dpm){return (lastResult=mGraphin.gDrawPath(mHandle,dpm))==GRAPHIN_OK;} |
|---|
| 178 |
|
|---|
| 179 |
// end of path opearations |
|---|
| 180 |
|
|---|
| 181 |
// SECTION: affine tranformations: |
|---|
| 182 |
|
|---|
| 183 |
bool rotate(ANGLE radians){return (lastResult=mGraphin.gRotate(mHandle,radians,null,null))==GRAPHIN_OK;} |
|---|
| 184 |
|
|---|
| 185 |
bool rotate(ANGLE radians,POS center_x,POS center_y){return (lastResult=mGraphin.gRotate(mHandle,radians,¢er_x,¢er_y))==GRAPHIN_OK;} |
|---|
| 186 |
|
|---|
| 187 |
bool translate(POS cx,POS cy){return (lastResult=mGraphin.gTranslate(mHandle,cx,cy))==GRAPHIN_OK;} |
|---|
| 188 |
|
|---|
| 189 |
bool scale(REAL x,REAL y){return (lastResult=mGraphin.gScale(mHandle,x,y))==GRAPHIN_OK;} |
|---|
| 190 |
|
|---|
| 191 |
bool skew(REAL dx,REAL dy){return (lastResult=mGraphin.gSkew(mHandle,dx,dy))==GRAPHIN_OK;} |
|---|
| 192 |
|
|---|
| 193 |
// all above in one shot |
|---|
| 194 |
bool transform(POS m11,POS m12,POS m21,POS m22,POS dx,POS dy){return (lastResult=mGraphin.gTransform(mHandle,m11,m12,m21,m22,dx,dy))==GRAPHIN_OK;} |
|---|
| 195 |
|
|---|
| 196 |
// end of affine tranformations. |
|---|
| 197 |
|
|---|
| 198 |
// SECTION: state save/restore |
|---|
| 199 |
|
|---|
| 200 |
bool stateSave(){return (lastResult=mGraphin.gStateSave(mHandle))==GRAPHIN_OK;} |
|---|
| 201 |
|
|---|
| 202 |
bool stateRestore(){return (lastResult=mGraphin.gStateRestore(mHandle))==GRAPHIN_OK;} |
|---|
| 203 |
|
|---|
| 204 |
// end of state save/restore |
|---|
| 205 |
|
|---|
| 206 |
// SECTION: drawing attributes |
|---|
| 207 |
|
|---|
| 208 |
// set line width for subsequent drawings. |
|---|
| 209 |
bool lineWidth(DIM width){return (lastResult=mGraphin.gLineWidth(mHandle,width))==GRAPHIN_OK;} |
|---|
| 210 |
|
|---|
| 211 |
bool noLine() {return lineWidth(0.0);} |
|---|
| 212 |
|
|---|
| 213 |
bool lineColor(HColor c) {return (lastResult=mGraphin.gLineColor(mHandle,graphinColor(c)))==GRAPHIN_OK;} |
|---|
| 214 |
|
|---|
| 215 |
bool lineCap(LINE_CAP_TYPE ct){return (lastResult=mGraphin.gLineCap(mHandle,ct))==GRAPHIN_OK;} |
|---|
| 216 |
|
|---|
| 217 |
bool lineJoin(LINE_JOIN_TYPE jt){return (lastResult=mGraphin.gLineJoin(mHandle,jt))==GRAPHIN_OK;} |
|---|
| 218 |
|
|---|
| 219 |
// color for solid fills |
|---|
| 220 |
bool fillColor(HColor c){return (lastResult=mGraphin.gFillColor(mHandle,graphinColor(c)))==GRAPHIN_OK;} |
|---|
| 221 |
|
|---|
| 222 |
bool noFill(){return fillColor(*HColor(0,0,0,0xff));} |
|---|
| 223 |
|
|---|
| 224 |
// setup parameters of linear gradient of lines. |
|---|
| 225 |
bool lineLinearGradient(POS x1,POS y1,POS x2,POS y2,HColorStop[] stops){return (lastResult=mGraphin.gLineGradientLinear(mHandle,x1,y1,x2,y2,stops.ptr,stops.length))==GRAPHIN_OK;} |
|---|
| 226 |
bool lineLinearGradient(POS x1,POS y1,POS x2,POS y2,HColor c1,HColor c2){auto stops = [ *HColorStop(graphinColor(c1),0.0),*HColorStop(graphinColor(c2),1.0) ];return fillLinearGradient(x1,y1,x2,y2,stops); |
|---|
| 227 |
} |
|---|
| 228 |
|
|---|
| 229 |
// setup parameters of linear gradient of fills. |
|---|
| 230 |
bool fillLinearGradient(POS x1,POS y1,POS x2,POS y2,HColorStop[] stops){return (lastResult=mGraphin.gFillGradientLinear(mHandle,x1,y1,x2,y2,stops.ptr,stops.length))==GRAPHIN_OK;} |
|---|
| 231 |
|
|---|
| 232 |
bool fillLinearGradient(POS x1,POS y1,POS x2,POS y2,HColor c1,HColor c2){auto stops = [ *HColorStop(graphinColor(c1),0.0),*HColorStop(graphinColor(c2),1.0) ];return fillLinearGradient(x1,y1,x2,y2,stops); |
|---|
| 233 |
} |
|---|
| 234 |
|
|---|
| 235 |
// setup parameters of line gradient radial fills. |
|---|
| 236 |
bool lineRadialGradient(POS x,POS y,DIM radii,HColorStop[] stops){return (lastResult=mGraphin.gFillGradientRadial(mHandle,x,y,radii,stops.ptr,stops.length))==GRAPHIN_OK;} |
|---|
| 237 |
|
|---|
| 238 |
bool lineRadialGradient(POS x,POS y,DIM radii,HColor c1,HColor c2){auto stops = [ *HColorStop(graphinColor(c1),0.0),*HColorStop(graphinColor(c2),1.0) ];return lineRadialGradient(x,y,radii,stops); |
|---|
| 239 |
} |
|---|
| 240 |
|
|---|
| 241 |
// setup parameters of gradient radial fills. |
|---|
| 242 |
bool fillRadialGradient(POS x,POS y,DIM radii,HColorStop[] stops){return (lastResult=mGraphin.gFillGradientRadial(mHandle,x,y,radii,stops.ptr,stops.length))==GRAPHIN_OK;} |
|---|
| 243 |
|
|---|
| 244 |
bool fillRadialGradient(POS x,POS y,DIM radii,HColor c1,HColor c2){auto stops = [ *HColorStop(graphinColor(c1),0.0),*HColorStop(graphinColor(c2),1.0) ];return fillRadialGradient(x,y,radii,stops); |
|---|
| 245 |
} |
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 |
bool fillMode(bool even_odd /* false - fill_non_zero */){return (lastResult=mGraphin.gFillMode(mHandle,even_odd))==GRAPHIN_OK;} |
|---|
| 249 |
|
|---|
| 250 |
// SECTION: text |
|---|
| 251 |
|
|---|
| 252 |
// define font attributes for all subsequent text operations. |
|---|
| 253 |
bool font(char[] name,DIM size,bool bold = false,bool italic = false,ANGLE angle = 0){return (lastResult=mGraphin.gSetFont(mHandle,toStringz(name),size,bold,italic,angle))==GRAPHIN_OK;} |
|---|
| 254 |
|
|---|
| 255 |
// draw text at x,y with text alignment |
|---|
| 256 |
bool text(POS x,POS y,char[] t){auto str=toString16(t);return (lastResult=mGraphin.gText(mHandle,x,y,str.ptr,str.length))==GRAPHIN_OK; |
|---|
| 257 |
} |
|---|
| 258 |
|
|---|
| 259 |
// calculates width of the text string |
|---|
| 260 |
DIM textWidth(char[] t) |
|---|
| 261 |
{ |
|---|
| 262 |
DIM width; |
|---|
| 263 |
auto str=toString16(t); |
|---|
| 264 |
if((lastResult=mGraphin.gTextWidth(mHandle,str.ptr,str.length,&width))==GRAPHIN_OK) return width; |
|---|
| 265 |
else return -1; |
|---|
| 266 |
} |
|---|
| 267 |
|
|---|
| 268 |
// returns height and ascent of the font. |
|---|
| 269 |
bool fontMetrics(ref DIM height,ref DIM ascent){return (lastResult=mGraphin.gFontMetrics(mHandle,&height,&ascent))==GRAPHIN_OK;} |
|---|
| 270 |
|
|---|
| 271 |
// set text alignments |
|---|
| 272 |
bool textAlignment(TEXT_ALIGNMENT x,TEXT_ALIGNMENT y){return (lastResult=mGraphin.gTextAlignment(mHandle,x,y))==GRAPHIN_OK;} |
|---|
| 273 |
|
|---|
| 274 |
// SECTION: image rendering |
|---|
| 275 |
|
|---|
| 276 |
// draws img onto the graphics surface with current transformation applied(scale,rotation). expensive |
|---|
| 277 |
bool drawImage(HImage pimg,POS x,POS y,DIM w,DIM h,UINT ix,UINT iy,UINT iw,UINT ih){return (lastResult=mGraphin.gDrawImage(mHandle,pimg.handle,x,y,&w,&h,&ix,&iy,&iw,&ih))==GRAPHIN_OK;} |
|---|
| 278 |
// draws whole img onto the graphics surface with current transformation applied(scale,rotation). expensive |
|---|
| 279 |
bool drawImage(HImage pimg,POS x,POS y){return (lastResult=mGraphin.gDrawImage(mHandle,pimg.handle,x,y,null,null,null,null,null,null))==GRAPHIN_OK;} |
|---|
| 280 |
// blends image bits with bits of the surface. no affine transformations. less expensive |
|---|
| 281 |
bool blendImage(HImage pimg,POS x,POS y,UINT opacity,UINT ix,UINT iy,UINT iw,UINT ih){return (lastResult=mGraphin.gBlendImage(mHandle,pimg.handle,x,y,opacity,&ix,&iy,&iw,&ih))==GRAPHIN_OK;} |
|---|
| 282 |
// blends image bits with bits of the surface. no affine transformations. less expensive |
|---|
| 283 |
bool blendImage(HImage pimg,POS x,POS y,UINT opacity){return (lastResult=mGraphin.gBlendImage(mHandle,pimg.handle,x,y,opacity,null,null,null,null))==GRAPHIN_OK;} |
|---|
| 284 |
// blits image bits onto underlying pixel buffer. no affine transformations. |
|---|
| 285 |
bool blitImage(HImage pimg,POS x,POS y,UINT ix,UINT iy,UINT iw,UINT ih){return (lastResult=mGraphin.gBlitImage(mHandle,pimg.handle,x,y,&ix,&iy,&iw,&ih))==GRAPHIN_OK;} |
|---|
| 286 |
// blits image bits onto underlying pixel buffer. no affine transformations. |
|---|
| 287 |
bool blitImage(HImage pimg,POS x,POS y){return (lastResult=mGraphin.gBlitImage(mHandle,pimg.handle,x,y,null,null,null,null))==GRAPHIN_OK;} |
|---|
| 288 |
|
|---|
| 289 |
// SECTION: coordinate space |
|---|
| 290 |
|
|---|
| 291 |
bool worldToScreen(ref POS inout_x,ref POS inout_y){return (lastResult=mGraphin.gWorldToScreen(mHandle,&inout_x,&inout_y))==GRAPHIN_OK;} |
|---|
| 292 |
|
|---|
| 293 |
bool worldToScreen(ref DIM inout_length){return (lastResult=mGraphin.gWorldToScreen(mHandle,&inout_length,null))==GRAPHIN_OK;} |
|---|
| 294 |
|
|---|
| 295 |
bool screenToWorld(ref POS inout_x,ref POS inout_y){return (lastResult=mGraphin.gScreenToWorld(mHandle,&inout_x,&inout_y))==GRAPHIN_OK;} |
|---|
| 296 |
|
|---|
| 297 |
bool screenToWorld(ref DIM inout_length){return (lastResult=mGraphin.gScreenToWorld(mHandle,&inout_length,null))==GRAPHIN_OK;} |
|---|
| 298 |
|
|---|
| 299 |
// SECTION: clipping |
|---|
| 300 |
|
|---|
| 301 |
bool setClipBox(POS x1,POS y1,POS x2,POS y2){return (lastResult=mGraphin.gSetClipBox(mHandle,x1,y1,x2,y2))==GRAPHIN_OK;} |
|---|
| 302 |
|
|---|
| 303 |
bool getClipBox(ref POS x1,ref POS y1,ref POS x2,ref POS y2){return (lastResult=mGraphin.gGetClipBox(mHandle,&x1,&y1,&x2,&y2))==GRAPHIN_OK;} |
|---|
| 304 |
|
|---|
| 305 |
bool visible(POS x,POS y) |
|---|
| 306 |
{ |
|---|
| 307 |
BOOL is_in = 0; |
|---|
| 308 |
return (lastResult=mGraphin.gPointInClipBox(mHandle,x,y,&is_in))==GRAPHIN_OK; |
|---|
| 309 |
return is_in != 0; |
|---|
| 310 |
} |
|---|
| 311 |
|
|---|
| 312 |
bool visible(POS x1,POS y1,POS x2,POS y2) |
|---|
| 313 |
{ |
|---|
| 314 |
BOOL is_in = 0; |
|---|
| 315 |
return (lastResult=mGraphin.gRectInClipBox(mHandle,x1,y1,x2,y2,&is_in))==GRAPHIN_OK; |
|---|
| 316 |
return is_in != 0; |
|---|
| 317 |
} |
|---|
| 318 |
|
|---|
| 319 |
GRAPHIN_RESULT lastResult; |
|---|
| 320 |
char[] lastResultMsg() {return graphinResultMsg(lastResult);} |
|---|
| 321 |
|
|---|
| 322 |
protected: |
|---|
| 323 |
HGFX mHandle; |
|---|
| 324 |
static Graphin *mGraphin; |
|---|
| 325 |
} |
|---|
| 326 |
|
|---|
| 327 |
struct HColor |
|---|
| 328 |
{ |
|---|
| 329 |
byte r,g,b,a; |
|---|
| 330 |
|
|---|
| 331 |
static HColor* opCall() |
|---|
| 332 |
{ |
|---|
| 333 |
auto ret=new HColor; |
|---|
| 334 |
ret.a=cast(byte)0xff; |
|---|
| 335 |
return ret; |
|---|
| 336 |
} |
|---|
| 337 |
|
|---|
| 338 |
static HColor* opCall(uint rgbt=0x000000ff) |
|---|
| 339 |
{ |
|---|
| 340 |
auto ret=new HColor; |
|---|
| 341 |
ret.r=rgbt & 0xff; |
|---|
| 342 |
ret.g=(rgbt & 0xff00) >> 8; |
|---|
| 343 |
ret.b=(rgbt & 0xff0000) >> 16; |
|---|
| 344 |
ret.a=(rgbt & 0xff000000) >> 24; |
|---|
| 345 |
return ret; |
|---|
| 346 |
} |
|---|
| 347 |
|
|---|
| 348 |
static HColor* opCall(uint red,uint green,uint blue,uint alpha=0) |
|---|
| 349 |
{ |
|---|
| 350 |
auto ret=new HColor; |
|---|
| 351 |
ret.r=cast(byte)red; |
|---|
| 352 |
ret.g=cast(byte)green; |
|---|
| 353 |
ret.b=cast(byte)blue; |
|---|
| 354 |
ret.a=cast(byte)alpha; |
|---|
| 355 |
return ret; |
|---|
| 356 |
} |
|---|
| 357 |
|
|---|
| 358 |
HColor* clone() |
|---|
| 359 |
{ |
|---|
| 360 |
auto ret=new HColor; |
|---|
| 361 |
*ret=*this; |
|---|
| 362 |
return ret; |
|---|
| 363 |
} |
|---|
| 364 |
|
|---|
| 365 |
bool transparent() {return a == 0xff;} |
|---|
| 366 |
|
|---|
| 367 |
/*HColor* parse(char[] text,HColor *default_value = HColor()) |
|---|
| 368 |
{ |
|---|
| 369 |
if(text.length == 0) |
|---|
| 370 |
return default_value; |
|---|
| 371 |
if(text[0] == '#') // #xxx,#xxxx,#xxxxxx,#xxxxxxxx |
|---|
| 372 |
{ |
|---|
| 373 |
int R = 0,G = 0,B = 0,T = 0; |
|---|
| 374 |
switch(text.length) |
|---|
| 375 |
{ |
|---|
| 376 |
case 4: swscanf(text.start+1 ,L"%1x%1x%1x",&R,&G,&B);R <<= 4;G <<= 4;B <<= 4;break; |
|---|
| 377 |
case 5: swscanf(text.start+1 ,L"%1x%1x%1x%1x",&R,&G,&B,&T);R <<= 4;G <<= 4;B <<= 4;T <<= 4;break; |
|---|
| 378 |
case 7: swscanf(text.start+1 ,L"%2x%2x%2x",&R,&G,&B);break; |
|---|
| 379 |
case 9: swscanf(text.start+1 ,L"%2x%2x%2x%2x",&R,&G,&B,&T);break; |
|---|
| 380 |
default: return default_value; |
|---|
| 381 |
} |
|---|
| 382 |
return color(R,G,B,T); |
|---|
| 383 |
} |
|---|
| 384 |
else if(text.like(L"rgb(*)")) // rgb(r,g,b),rgb(r,g,b,a) |
|---|
| 385 |
{ |
|---|
| 386 |
text.start += 4;text.length -= 5; |
|---|
| 387 |
unsigned ca[4] = {0};aux::wchars tok;aux::wtokens toks(text,L","); |
|---|
| 388 |
for(int n = 0;n < 4;++n) |
|---|
| 389 |
{ |
|---|
| 390 |
if(!toks.next(tok)) break; |
|---|
| 391 |
ca[n] = aux::to_uint(tok); |
|---|
| 392 |
if(tok.start[tok.length] == '%') ca[n] =(ca[n] * 255) / 100; |
|---|
| 393 |
} |
|---|
| 394 |
return color(aux::limit(ca[0],0U,255U),aux::limit(ca[1],0U,255U),aux::limit(ca[2],0U,255U),aux::limit(ca[3],0U,255U)); |
|---|
| 395 |
} |
|---|
| 396 |
return default_value; |
|---|
| 397 |
}*/ |
|---|
| 398 |
} |
|---|
| 399 |
|
|---|
| 400 |
private Graphin* gApi() |
|---|
| 401 |
{ |
|---|
| 402 |
static Graphin *mGraphin; |
|---|
| 403 |
if(mGraphin is null) mGraphin=HTMLayoutGetGraphin(); |
|---|
| 404 |
return mGraphin; |
|---|
| 405 |
} |
|---|
| 406 |
|
|---|
| 407 |
COLOR graphinColor(HColor c) {return gApi.RGBT(c.r,c.g,c.b,c.a);} |
|---|
| 408 |
COLOR graphinColor(uint r,uint g,uint b,uint a = 0) {return gApi.RGBT(r,g,b,a);} |
|---|
| 409 |
|
|---|
| 410 |
char[] graphinResultMsg(GRAPHIN_RESULT res) |
|---|
| 411 |
{ |
|---|
| 412 |
if(res==GRAPHIN_PANIC) return "GRAPHIN_PANIC - e.g. not enough memory"; |
|---|
| 413 |
else if(res==GRAPHIN_OK) return "GRAPHIN_OK"; |
|---|
| 414 |
else if(res==GRAPHIN_BAD_PARAM) return "GRAPHIN_BAD_PARAM - bad parameter"; |
|---|
| 415 |
else if(res==GRAPHIN_FAILURE) return "GRAPHIN_FAILURE - operation failed,e.g. restore() without save()"; |
|---|
| 416 |
else if(res==GRAPHIN_NOTSUPPORTED) return "GRAPHIN_NOTSUPPORTED - the platform does not support requested feature"; |
|---|
| 417 |
else return null; |
|---|
| 418 |
} |
|---|