From 354467383d74494a26251850be18c8a2cfc5db10 Mon Sep 17 00:00:00 2001 From: William Joye Date: Thu, 23 Mar 2017 12:40:44 -0400 Subject: rename --- tkmacosx/macosxlib.m | 180 +++++++++++ tkmacosx/tkmacosx.m | 823 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1003 insertions(+) create mode 100644 tkmacosx/macosxlib.m create mode 100644 tkmacosx/tkmacosx.m diff --git a/tkmacosx/macosxlib.m b/tkmacosx/macosxlib.m new file mode 100644 index 0000000..65e51a8 --- /dev/null +++ b/tkmacosx/macosxlib.m @@ -0,0 +1,180 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "tkmacosx.h" +#include "macosxlib.h" + +void macosxBegin() +{ + if (tkmacosx) + tkmacosx->begin(); +} + +void macosxEnd() +{ + if (tkmacosx) + tkmacosx->end(); +} + +void macosxColor(XColor* clr) +{ + if (clr) { + float red = clr->red/float(USHRT_MAX); + float green = clr->green/float(USHRT_MAX); + float blue = clr->blue/float(USHRT_MAX); + + if (tkmacosx) + tkmacosx->color(red,green,blue); + } +} + +void macosxWidth(float ww) +{ + if (tkmacosx) + tkmacosx->width(ww); +} + +void macosxDash(float* d, int n) +{ + if (tkmacosx) + tkmacosx->dash(d,n); +} + +void macosxFont(const char* f, float s) +{ + if (tkmacosx) + tkmacosx->font(f,s); +} + +void macosxClip(Vector v, Vector s) +{ + if (tkmacosx) { + Vector vv1 = v*tkmacosx->getCanvasToPage(); + Vector vv2 = (v+s)*tkmacosx->getCanvasToPage(); + Vector ss = vv2-vv1; + tkmacosx->clip(vv1[0],vv1[1],ss[0],ss[1]); + } +} + +void macosxNewPath() +{ + if (tkmacosx) { + tkmacosx->newpath(); + } +} + +void macosxStroke() +{ + if (tkmacosx) { + tkmacosx->stroke(); + } +} + +void macosxFill() +{ + if (tkmacosx) { + tkmacosx->fill(); + } +} + +void macosxArc(Vector v, float rad, float ang1, float ang2) +{ + if (tkmacosx) { + Vector vv = v*tkmacosx->getCanvasToPage(); + tkmacosx->arc(vv[0], vv[1], rad, ang1, ang2); + } +} + +void macosxCurve(Vector v0, Vector t0, Vector t1, Vector v1) +{ + if (tkmacosx) { + Vector vv0 = v0*tkmacosx->getCanvasToPage(); + Vector tt0 = t0*tkmacosx->getCanvasToPage(); + Vector tt1 = t1*tkmacosx->getCanvasToPage(); + Vector vv1 = v1*tkmacosx->getCanvasToPage(); + + tkmacosx->curve(vv0[0], vv0[1], tt0[0], tt0[1], + tt1[0], tt1[1], vv1[0], vv1[1]); + } +} + +void macosxDrawText(Vector v, float ang, const char* text) +{ + if (tkmacosx) { + Vector vv = v*tkmacosx->getCanvasToPage(); + tkmacosx->drawText(vv[0], vv[1], ang, text); + } +} + +void macosxDrawLine(Vector v0, Vector v1) +{ + if (tkmacosx) { + Vector vv0 = v0*tkmacosx->getCanvasToPage(); + Vector vv1 = v1*tkmacosx->getCanvasToPage(); + + int n = 2; + float x[2]; + float y[2]; + + x[0] = vv0[0]; + y[0] = vv0[1]; + x[1] = vv1[0]; + y[1] = vv1[1]; + + tkmacosx->drawLines(x,y,n); + } +} + +void macosxDrawLines(Vector* v, int n) +{ + if (tkmacosx) { + float xx[n]; + float yy[n]; + + for(int ii=0; iigetCanvasToPage(); + + xx[ii] = vv[0]; + yy[ii] = vv[1]; + } + + tkmacosx->drawLines(xx,yy,n); + } +} + +void macosxFillPolygon(Vector* v, int n) +{ + if (tkmacosx) { + float xx[n]; + float yy[n]; + + for(int ii=0; iigetCanvasToPage(); + + xx[ii] = vv[0]; + yy[ii] = vv[1]; + } + + tkmacosx->fillPolygon(xx,yy,n); + } +} + +void macosxDrawArc(Vector v, float rad, float ang1, float ang2) +{ + if (tkmacosx) { + Vector vv = v*tkmacosx->getCanvasToPage(); + tkmacosx->drawArc(vv[0], vv[1], rad, ang1, ang2); + } +} + +void macosxBitmapCreate(void* img, int width, int height, + const Vector& v, const Vector& s) +{ + if (tkmacosx) { + Vector vv1 = v*tkmacosx->getCanvasToPage(); + Vector vv2 = (v+s)*tkmacosx->getCanvasToPage(); + Vector ss = vv2-vv1; + tkmacosx->bitmapCreate(img, width, height, vv1[0], vv1[1], ss[0], ss[1]); + } +} diff --git a/tkmacosx/tkmacosx.m b/tkmacosx/tkmacosx.m new file mode 100644 index 0000000..5f44984 --- /dev/null +++ b/tkmacosx/tkmacosx.m @@ -0,0 +1,823 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include +#include +using namespace std; + +#include + +#include "tkmacosx.h" + +extern "C" { + int Tkmacosx_Init(Tcl_Interp* interp); + int TkmacosxCmd(ClientData data, Tcl_Interp *interp, int argc, + const char* argv[]); +} + +TkMacosx* tkmacosx=NULL; + +int Tkmacosx_Init(Tcl_Interp* interp) { + + if (Tcl_InitStubs(interp, TCL_PATCH_LEVEL, 0) == NULL) + return TCL_ERROR; + + if (Tk_InitStubs(interp, TK_PATCH_LEVEL, 0) == NULL) + return TCL_ERROR; + + Tcl_CreateCommand(interp, "macosx", TkmacosxCmd, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + + if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION)) + return TCL_ERROR; + + tkmacosx = new TkMacosx(interp); + + return tkmacosx ? TCL_OK : TCL_ERROR; +} + +int TkmacosxCmd(ClientData data,Tcl_Interp *interp,int argc,const char* argv[]) +{ + if (argc>=2) { + if (!strncmp(argv[1], "pm", 2)) + return tkmacosx->pm(argc, argv); + + if (!strncmp(argv[1], "locale", 2)) + return tkmacosx->locale(argc, argv); + else { + Tcl_AppendResult(interp, "macosx: unknown command: ", argv[1], NULL); + return TCL_ERROR; + } + } + else { + Tcl_AppendResult(interp, "usage: macosx ?locale?", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +TkMacosx::TkMacosx(Tcl_Interp* intp) +{ + interp = intp; + + showDialog = 0; + + status = noErr; + pageFormat = kPMNoPageFormat; + printSettings = kPMNoPrintSettings; + printSession = NULL; + context = NULL; +} + +TkMacosx::~TkMacosx() +{ + if (pageFormat != kPMNoPageFormat) + PMRelease(pageFormat); + if (printSettings != kPMNoPrintSettings) + PMRelease(printSettings); +} + +// Locale +int TkMacosx::locale(int argc, const char* argv[]) +{ + CFPropertyListRef preferences = + CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), + kCFPreferencesCurrentApplication); + if (preferences && CFGetTypeID(preferences) == CFArrayGetTypeID()) { + CFArrayRef prefArray = (CFArrayRef)preferences; + int nn = CFArrayGetCount (prefArray); + char buf[256]; + + for (int ii=0; ii= 3) { + if (!strncmp(argv[2], "print", 3)) + return tkmacosx->pmPrint(argc, argv); + else if (!strncmp(argv[2], "pagesetup", 3)) + return tkmacosx->pmPageSetup(); + else { + Tcl_AppendResult(interp, "tkmacosx pm: unknown command: ", argv[2], NULL); + return TCL_ERROR; + } + } + else { + Tcl_AppendResult(interp, "usage: tkmacosx pm ?print?pagesetup?", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +int TkMacosx::pmPrint(int argc, const char* argv[]) +{ + if (argc >= 4) { + if (!strncmp(argv[3], "begin", 3)) + return tkmacosx->pmPrintBegin(argc, argv); + else if (!strncmp(argv[3], "end", 3)) + return tkmacosx->pmPrintEnd(); + else if (!strncmp(argv[3], "text", 3)) + return tkmacosx->pmPrintText(argc, argv); + else { + Tcl_AppendResult(interp, "tkmacosx pm print: unknown command: ", argv[2], NULL); + return TCL_ERROR; + } + } + else { + Tcl_AppendResult(interp, "usage: tkmacosx pm print: ?begin?end?text?", NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +int TkMacosx::pmPrintBegin(int argc, const char* argv[]) +{ + // canvas width and height + double width =0; + double height =0; + if (argc >= 7) { + string w(argv[4]); + istringstream ww(w); + ww >> width; + + string h(argv[5]); + istringstream hh(h); + hh >> height; + + if (width <=0 || height <=0) { + Tcl_AppendResult(interp, "Invalid width or height.", NULL); + return TCL_ERROR; + } + + if (!strncmp(argv[6], "yes", 2)) + showDialog = 1; + else if (!strncmp(argv[6], "no", 2)) + showDialog = 0; + } + else { + Tcl_AppendResult(interp, "usage: tkmacosx pm print begin: ?width height yes|no?", NULL); + return TCL_ERROR; + } + + Vector canvas(width,height); + + // print session + status = PMCreateSession(&printSession); + if (status != noErr) + goto error; + + // pagesetup + if (pageFormat == kPMNoPageFormat) { + status = PMCreatePageFormat(&pageFormat); + if (status != noErr) + goto error; + + if (pageFormat != kPMNoPageFormat) { + status = PMSessionDefaultPageFormat(printSession, pageFormat); + if (status != noErr) + goto error; + } + } + else { + status = PMSessionValidatePageFormat(printSession, pageFormat, + kPMDontWantBoolean); + if (status != noErr) + goto error; + } + + status = PMSessionValidatePageFormat(printSession, pageFormat, + kPMDontWantBoolean); + if (status != noErr) + goto error; + + // printsettings + if (printSettings == kPMNoPrintSettings) { + status = PMCreatePrintSettings(&printSettings); + if (status != noErr) + goto error; + + if (printSettings != kPMNoPrintSettings) { + status = PMSessionDefaultPrintSettings(printSession, printSettings); + if (status != noErr) + goto error; + } + } + else { + status = PMSessionValidatePrintSettings(printSession, printSettings, + kPMDontWantBoolean); + if (status != noErr) + goto error; + } + + // range + status = PMSetPageRange(printSettings, 1, 1); + if (status != noErr) + goto error; + + // dialog + if (showDialog) { + Boolean rr =0; +// status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &rr); + if (status != noErr) + goto error; + + // user clicked cancel + if (!rr) { + Tcl_AppendResult(interp, "0", NULL); + goto done; + } + } + + // print loop + { + CFStringRef jobName = CFSTR("SAOImage DS9"); + status = PMPrintSettingsSetJobName(printSettings, jobName); + if (status != noErr) + goto error; + } + + // set pages + { + UInt32 firstPage =0; + UInt32 lastPage =0; + status = PMGetFirstPage(printSettings, &firstPage); + if (status != noErr) + goto error; + status = PMGetLastPage(printSettings, &lastPage); + if (status != noErr) + goto error; + if (1 < lastPage) + lastPage = 1; + + status = PMSetFirstPage(printSettings, firstPage, false); + if (status != noErr) + goto error; + status = PMSetLastPage(printSettings, lastPage, false); + if (status != noErr) + goto error; + } + +// status = PMSessionBeginCGDocument(printSession, printSettings, pageFormat); + if (status != noErr) + goto error; + +// status = PMSessionBeginPage(printSession, pageFormat, NULL); + if (status != noErr) + goto error; + + status = PMSessionGetCGGraphicsContext(printSession, &context); + if (status != noErr) + goto error; + + { + PMRect pageRect; + status = PMGetAdjustedPageRect(pageFormat, &pageRect); + if (status != noErr) + goto error; + PMRect paperRect; + status = PMGetAdjustedPaperRect(pageFormat, &paperRect); + if (status != noErr) + goto error; + double scale; + status = PMGetScale(pageFormat, &scale); + if (status != noErr) + goto error; + PMOrientation orient; + status = PMGetOrientation(pageFormat, &orient); + if (status != noErr) + goto error; + Matrix orientation; + switch (orient) { + case kPMPortrait: + case kPMLandscape: + break; + case kPMReverseLandscape: + orientation = FlipX(); + break; + } + + // build context transformation matrix + Vector page(pageRect.right-pageRect.left,pageRect.bottom-pageRect.top); + Vector paper(paperRect.right-paperRect.left, + paperRect.bottom-paperRect.top); + Vector origin(pageRect.left,pageRect.top); + float ss; + if (page[0]/canvas[0] < page[1]/canvas[1]) + ss = page[0]/canvas[0]*.95; + else + ss = page[1]/canvas[1]*.95; + + Vector cp = page/2; + CGContextTranslateCTM(context, cp[0], cp[1]); + CGContextScaleCTM(context, ss, ss); + CGContextScaleCTM(context, scale/100, scale/100); + CGContextTranslateCTM(context, -cp[0], -cp[1]); + + // build coordinate matrix + canvasToPage = Translate(-canvas/2) * + FlipY() * + orientation * + Translate(paper/2) * + Translate(origin); + } + + // ok, we are good for go + Tcl_AppendResult(interp, "1", NULL); + + done: + return TCL_OK; + + error: + cerr << "PM Error Code: " << status << endl; + return TCL_ERROR; +} + +int TkMacosx::pmPrintEnd() +{ +// status = PMSessionEndPage(printSession); + if (status != noErr) + goto error; +// status = PMSessionEndDocument(printSession); + if (status != noErr) + goto error; + + status = PMSessionError(printSession); + if (status != noErr) + goto error; + + PMRelease(printSession); + printSession = NULL; + return TCL_OK; + + error: + cerr << "PM Error Code: " << status << endl; + PMRelease(printSession); + printSession = NULL; + return TCL_ERROR; +} + +int TkMacosx::pmPrintText(int argc, const char* argv[]) +{ + const int fontSize =12; + const float margin =36; + + float top; + float left; + float bottom; + float right; + + UInt32 firstPage =1; + UInt32 currentPage =1; + UInt32 maxPage; + UInt32 lastPage; + + int numLines =1; + + float xx; + float yy; + char* ss; + char* st; + + char* sstr =NULL; + char* estr =NULL; + + // text + if (argc >= 5) + ; + else { + Tcl_AppendResult(interp, "usage: tkmacosx pm print text: ?text?", NULL); + return TCL_ERROR; + } + + if (!argv[4]) + goto error; + + // dup text + sstr = new char[strlen(argv[4])+1]; + estr = sstr; + if (!sstr) + goto error; + + strcpy(sstr,argv[4]); + sstr[strlen(argv[4])] = '\0'; + + // sub ends for \n and count lines + while (estr && *estr) { + if (*estr == '\n') { + *estr = '\0'; + numLines++; + } + estr++; + } + + // print session + status = PMCreateSession(&printSession); + if (status != noErr) + goto error; + + // pagesetup + if (pageFormat == kPMNoPageFormat) { + status = PMCreatePageFormat(&pageFormat); + if (status != noErr) + goto error; + + if (pageFormat != kPMNoPageFormat) { + status = PMSessionDefaultPageFormat(printSession, pageFormat); + if (status != noErr) + goto error; + } + } + else { + status = PMSessionValidatePageFormat(printSession, pageFormat, + kPMDontWantBoolean); + if (status != noErr) + goto error; + } + + status = PMSessionValidatePageFormat(printSession, pageFormat, + kPMDontWantBoolean); + if (status != noErr) + goto error; + + // printsettings + if (printSettings == kPMNoPrintSettings) { + status = PMCreatePrintSettings(&printSettings); + if (status != noErr) + goto error; + + if (printSettings != kPMNoPrintSettings) { + status = PMSessionDefaultPrintSettings(printSession, printSettings); + if (status != noErr) + goto error; + } + } + else { + status = PMSessionValidatePrintSettings(printSession, printSettings, + kPMDontWantBoolean); + if (status != noErr) + goto error; + } + + // calc page size + PMRect pageRect; + status = PMGetAdjustedPageRect(pageFormat, &pageRect); + if (status != noErr) + goto error; + PMRect paperRect; + status = PMGetAdjustedPaperRect(pageFormat, &paperRect); + if (status != noErr) + goto error; + double scale; + status = PMGetScale(pageFormat, &scale); + if (status != noErr) + goto error; + PMOrientation orient; + status = PMGetOrientation(pageFormat, &orient); + if (status != noErr) + goto error; + + top =pageRect.top + margin; + left =pageRect.left + margin; + bottom =pageRect.bottom - margin; + right =pageRect.right - margin; + + // calc range + maxPage = int(numLines / int((bottom-top)/fontSize) ) +1; + lastPage =maxPage; + + status = PMSetPageRange(printSettings, firstPage, lastPage); + if (status != noErr) + goto error; + + // dialog + { + Boolean rr =0; +// status = PMSessionPrintDialog(printSession, printSettings, pageFormat, &rr); + if (status != noErr) + goto error; + + // user clicked cancel + if (!rr) { + Tcl_AppendResult(interp, "0", NULL); + goto done; + } + } + + // job name + { +// CFStringRef jobName = CFSTR("SAOImage DS9"); +// status = PMSetJobNameCFString(printSettings, jobName); + if (status != noErr) + goto error; + } + + // get pages + status = PMGetFirstPage(printSettings, &firstPage); + if (status != noErr) + goto error; + status = PMGetLastPage(printSettings, &lastPage); + if (status != noErr) + goto error; + + // check pages + if (firstPage < 1) + firstPage =1; + if (firstPage > maxPage) + firstPage = maxPage; + + if (lastPage < firstPage) + lastPage = firstPage; + if (lastPage > maxPage) + lastPage = maxPage; + + // set pages + status = PMSetFirstPage(printSettings, firstPage, false); + if (status != noErr) + goto error; + status = PMSetLastPage(printSettings, lastPage, false); + if (status != noErr) + goto error; + + // start + //status = PMSessionBeginCGDocument(printSession, printSettings, pageFormat); + if (status != noErr) + goto error; + + // loop over pages + xx = left; + yy = top; + ss = sstr; + st = sstr; + + while (currentPage <= lastPage) { +// status = PMSessionBeginPage(printSession, pageFormat, NULL); + if (status != noErr) + goto error; + + status = PMSessionGetCGGraphicsContext(printSession, &context); + if (status != noErr) + goto error; + + // set context +// CGContextSelectFont(context, "Courier", fontSize, kCGEncodingMacRoman); + CGContextSetRGBFillColor(context,0,0,0,1); + CGContextSetTextDrawingMode (context, kCGTextFill); + + // matrix + Vector paper(paperRect.right-paperRect.left, + paperRect.bottom-paperRect.top); + Matrix mm = Translate(-paper/2) * + Translate(0,fontSize) * + FlipY() * + Translate(paper/2); + + // line by line + while (ss < estr) { + Vector vv = Vector(xx,yy) * mm; + vv = Vector(); // remove waj + // CGContextShowTextAtPoint (context, vv[0], vv[1], ss, strlen(ss)); + + while (*st++); + ss = st; + yy += fontSize; + + if (yy > bottom) { + yy = top; + break; + } + } + + // status = PMSessionEndPage(printSession); + if (status != noErr) + goto error; + + currentPage++; + } + +// status = PMSessionEndDocument(printSession); + if (status != noErr) + goto error; + + status = PMSessionError(printSession); + if (status != noErr) + goto error; + + done: + if (printSession) + PMRelease(printSession); + printSession = NULL; + + if (sstr) + delete sstr; + + return TCL_OK; + + error: + cerr << "PM Error Code: " << status << endl; + if (printSession) + PMRelease(printSession); + printSession = NULL; + + if (sstr) + delete sstr; + + return TCL_ERROR; +} + +int TkMacosx::pmPageSetup() +{ + // print session + status = PMCreateSession(&printSession); + if (status != noErr) + goto error; + + // pagesetup + if (pageFormat == kPMNoPageFormat) { + status = PMCreatePageFormat(&pageFormat); + if (status != noErr) + goto error; + + if (pageFormat != kPMNoPageFormat) { + status = PMSessionDefaultPageFormat(printSession, pageFormat); + if (status != noErr) + goto error; + } + } + else { + status = PMSessionValidatePageFormat(printSession, pageFormat, + kPMDontWantBoolean); + if (status != noErr) + goto error; + } + + //Boolean rr =0; + //status = PMSessionPageSetupDialog(printSession, pageFormat, &rr); + if (status != noErr) + goto error; + + PMRelease(printSession); + printSession = NULL; + return TCL_OK; + + error: + cerr << "PM Error Code: " << status << endl; + PMRelease(printSession); + printSession = NULL; + return TCL_ERROR; +} + +// drawing routines + +void TkMacosx::begin() +{ +// CGContextSaveGState(context); +} + +void TkMacosx::end() +{ +// CGContextRestoreGState(context); +} + +void TkMacosx::color(float red, float green, float blue) +{ +// CGContextSetRGBStrokeColor(context,red,green,blue,1); +// CGContextSetRGBFillColor(context,red,green,blue,1); +} + +void TkMacosx::width(float ww) +{ +// CGContextSetLineWidth(context,ww); +} + +void TkMacosx::dash(float* dd, int nn) +{ +// CGContextSetLineDash(context,0,(CGFloat*)dd,nn); +} + +void TkMacosx::font(const char* font, float size) +{ +// CGContextSelectFont(context, font, size, kCGEncodingMacRoman); +} + +void TkMacosx::clip(float x, float y, float w, float h) +{ +/* + CGContextBeginPath(context); + CGContextAddRect(context, CGRectMake(x,y,w,h)); + CGContextClosePath(context); + CGContextClip(context); +*/ +} + +void TkMacosx::newpath() +{ +// CGContextBeginPath(context); +} + +void TkMacosx::stroke() +{ +// CGContextStrokePath(context); +} + +void TkMacosx::fill() +{ +// CGContextEOFillPath(context); +} + +void TkMacosx::arc(float x, float y, float rad, float ang1, float ang2) +{ +// CGContextAddArc(context, x, y, rad, ang1, ang2, 0); +} + +void TkMacosx::curve(float x0, float y0, float u0, float v0, + float u1, float v1, float x1, float y1) +{ +/* + CGContextMoveToPoint(context, x0, y0); + CGContextAddCurveToPoint(context, u0, v0, u1, v1, x1, y1); +*/ +} + +void TkMacosx::drawText(float x, float y, float angle, const char* text) +{ +/* + CGAffineTransform mm = CGAffineTransformMakeRotation(angle); + CGContextSetTextMatrix(context, mm); + + CGContextSetTextDrawingMode (context, kCGTextFill); + CGContextShowTextAtPoint (context, x, y, text, strlen(text)); +*/ +} + +void TkMacosx::drawLines(float* x, float* y, int n) +{ +/* + CGContextBeginPath(context); + CGContextMoveToPoint(context, x[0], y[0]); + for (int ii=1; ii