/* GEDTEXT (GED) -- GED Text/Drill Functions */ /* GEDTEXT (GED) -- GED-Text-/Bohrungsfunktionen */ /* -- INTENDED FOR KEY-CALL USE -- */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101102) RELEASED FOR BAE V7.6. // rl (100119) BUGFIX: // Fixed multiline text edit rule loss problem. // rl (091021) RELEASED FOR BAE V7.4. // rl (090603) ENHANCEMENT: // Added clipboard text placement support. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (051103) ENHANCEMENT: // Added multiline text alternate origin support. // rl (051019) ENHANCEMENT: // Added multiline text table import function. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (030904) RELEASED FOR BAE V6.2. // rl (030410) ENHANCEMENT: // Added RMB layer change support. // Added full default element layer support. // rl (021209) RELEASED FOR BAE V6.0. // rl (021109) ENHANCEMENT: // Added multi line text support functions. // rl (020618) RELEASED FOR BAE V5.4. // rl (010724) ENHANCEMENT: // Adjusted dialog box sizes for Windows environment. // rl (010625) RELEASED FOR BAE V5.0. // rl (010405) ENHANCEMENT: // Added text rule preserving in text case change functions. // rl (010329) ENHANCEMENT: // Added drill power layer mask assignment functions. // rl (001206) ENHANCEMENT: // Added text plot width option. // rl (000509) RELEASED FOR BAE V4.6. // rl (990907) RELEASED FOR BAE V4.4. // rl (990907) BUGFIX: // Fixed problem with rotated and mirrored texts. // rl (980929) RELEASED FOR BAE V4.2. // mb (980712) ENHANCEMENT: // Pulldown menu delimiters introduced. // mb (980712) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (970604) CHANGE: // Applied figure list cross reference index access. // mb (970408) ENHANCEMENT: // New functions for changing mouse-selectable text // strings to upper case and/or lower case. // mb (970408) IMPROVEMENT: // Introduced screen redraw call for each change. // mb (960919) RELEASED FOR BAE V3.4. // mb (95) RELEASED FOR BAE V3.2. // mb (950222) IMPROVEMENT: // Avoid blank character creation during arc text generation. // mb (941213) IMPROVEMENT: // Abort on invalid class post-poned to text functions. // mb (941116) ORIGINAL CODING: // Retrieved from TEXTUTIL. // mb (941117) ENHANCEMENT: // Integrated TEXTCONV, TEXTDCV. // mb (94) RELEASED FOR BAE V3.0. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The gedtext User Language program provides a menu with a series // of advanced text and drill processing functions such as setting text // sizes, changing text layers, upper case text strings, lower case text // strings, converting texts to traces, areas, or lines, writing // texts on arcs, deleting texts with repetitive selection, assigning // drills to power layers, setting drills power layer heat trap mode etc. */ // Includes #include "baeparam.ulh" // User Language BAE param. access #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string UPRFCT = M("Text-/Bohrungs-Funktion selektieren!", "Select Text/Drill Function!"); string UPRFCT1 = M("Text&groesse setzen","Set Text &Size"); string UPRFCT2 = M("Text&lage setzen","Set Text &Layer"); string UPRFCT3 = M("Text St&iftbreite setzen","Set Text Plot &Width"); string UPRFCT4 = M("%Text->&Bahn/Flaeche","%Text->&Trace/Area"); string UPRFCT5 = M("Text->&Doklinie","Text->&Docline"); string UPRFCT6 = M("Text auf &Kreis","Text on Ar&c"); string UPRFCT7 = M("%Text Gro&ssschreibung","%Text &Upper Case"); string UPRFCT8 = M("Text Klei&nschreibung","Text L&ower Case"); string UPRFCT9 = M("%Text(e) l&oeschen","%D&elete Text(s)"); string UPRFCT10 = M("%&Font Editor","%&Font Editor"); string UPRFCT11 = M("%Bohrung &Versorgungslagen", "%Drill &Power Layers"); string UPRFCT12 = M("Bohrung &Waermefallen","Drill &Heat Traps"); string UPRFCT13 = M("%&Mehrzeilentext","%&Multi Line Text"); string UPRFCT14 = M("%Link zu ex&terner Datei", "%Li&nk to External File"); string UPRFCT15 = M("%Text aus &Zwischenablage", "%Place Clip&board Text"); string UPRMTEXTFCT = M("Mehrzeilentextfunktion selektieren!", "Select Multi Line Text Function!"); string UPRMFCT1 = M("&Neu","&Add"); string UPRMFCT2 = M("&Bewegen","&Move"); string UPRMFCT3 = M("&Kopieren","&Copy"); string UPRMFCT4 = M("&Aendern","&Edit"); string UPRMFCT5 = M("&Loeschen","&Delete"); string UPRMFCT6 = M("%&Groesse setzen","%Set Si&ze"); string UPRMFCT7 = M("Lage set&zen","Set &Layer"); string UPRMFCT8 = M("%&Selektieren","%&Select"); string UPRMFCT9 = M("D&eselektieren","Deselec&t"); string UPRMFCT10 = M("T&oggle","&Toggle"); string UPRMFCT11 = M("%&Tabelle einlesen","%&Import Table"); string UPRDPMODE = M("Linienbreitenfunktion waehlen!", "Select Polygon Line Width Function!"); string UPRDMODE1 = M("&Aendern","&Change"); string UPRDMODE2 = M("&Setzen","&Set"); string UPRDMODE3 = M("&Gruppe setzen","Set &Group"); string UPRDMODE4 = M("Gruppe s&kalieren","Sc&ale Group"); string UPRGRP = M("Bearbeitungsmodus waehlen!", "Select Element Mode!"); string UPRGRP0 = M("&Einzelelemente","&Single Elements"); string UPRGRP1 = M("&Gruppe","&Group"); string UPRTABFILE = M("Texttabellendatei ? ","Text Table File ? "); string UPRSELTNAME = M("Tabellendefinition ? ","Table Definition ? "); string UPRWSCALE = M("Stiftbreiten-Skalierungsfaktor ? ", "Plot Width Scale Factor ? "); string UPRSELTEXT = M("Text waehlen!","Select Text!"); string UPRTSIZEM = M("Textgroesse [mm] ? ","Text Size [mm] ? "); string UPRTSIZEI = M("Textgroesse [Inch] ? ","Text Size [Inch] ? "); string UPRTEXTWM = M("Default Text Stiftbreite [mm] ? ", "Default Text Pen Width [mm] ? "); string UPRTEXTWI = M("Default Text Stiftbreite [Inch] ? ", "Default Text Pen Width [Inch] ? "); string UPRTPWIDM = M("Text Stiftbreite (%.2fmm) ? ", "Text Pen Width (%.2fmm) ? "); string UPRTPWIDI = M("Text Stiftbreite [%.3f Inch] ? ", "Text Pen Width [Inch] ? "); string UPRTEXT = M("Text ? ","Text ? "); string UPRTCENTER = M("Bogen-Mittelpunkt waehlen!", "Select Arc Center!"); string UPRTSTART = M("Text-Startposition waehlen!", "Select Text Start Position!"); string UPRACLOCK = M("&Gegen Uhrzeigersinn","C&ounter-Clockwise"); string UPRCLOCK = M("&Im Uhrzeigersinn","&Clockwise"); string UPRTLAY = M("Lage fuer Text waehlen!","Select Text Layer!"); string UPRSELDRILL = M("Bohrung waehlen!","Select Drill!"); string UPRPOWLAY = M("Anschluss/Tangierung Versorgungslage %d", "Connection/cross of power layer %d"); string UPRHTMODE = M("Direktanschluss an Versorgungslage %d", "Direct connect to power layer %d"); string UPRPLMASKDIAL = M("Bohrung mit Klasse '%c' :", "Drill with class '%c' :"); string UPRPOWLMASK = M("Versorgungslagenmaske ? ","Power Layer Mask ? "); string UPRHTMASK = M("Direktanschlussmaske ? ", "Direct Connect Mask ? "); string UPRBALL = M("&Alle","&All"); string UPRBNONE = M("&Keine","&None"); string UPREDIT = M("!Neuer Text","!New Text"); string UPRDONE = M("&Fertig","&Done"); string UPRCONT = M("&Weiter","&Continue"); string UPRJUMPREL = M("%Sprung relati&v","%Jump Relati&ve"); string UPRJUMPABS = M("&Sprung absolut","&Jump Absolute"); string UPRSELLAY = M("%Lage &wechseln","%&Change Layer"); string UPREXTFILE = M("Link Zieldatei ? ","Link Target File ? "); string UPRFCTRPLC = M("Funktion '%s' ersetzen ?", "Replace function '%s' ?"); string REPTABLIST = M("Auswahl Tabellendefinition :", "Table Definition Selection :"); string REPTEXTCHG = M("%d Texte umgewandelt.","%d texts converted."); string ERRCHANGE = M("Aenderung nicht moeglich!", "Change not possible!"); string ERRPOLY = M("Fehler beim Erzeugen der Flaechen!", "Error creating areas!"); string ERRPATH = M("Fehler beim Erzeugen der Leiterbahnen!", "Error creating traces!"); string ERRTEXT = M("Fehler beim Erzeugen des Textes '%s'!", "Error creating text '%s'"); string ERRMTEXT = M("Text '%s' ist kein Mehrzeilentext!", "Text '%s' not part of a multi line text!"); string ERRDELETE = M("Fehler beim Loeschen des Textes '%s'", "Error deleting text '%s'"); string ERRLAYER = M("Ungueltige Textlage!","Invalid text layer!"); string ERRPOLYLAY = M("Ungueltige Lage fuer Polygonerzeugung!", "Invalid layer for polygon generation!"); string ERRILLPLMASK = M("Ungueltige Versorgungslagenmaske!", "Invalid power layer mask!"); string ERRILLHTMASK = M("Ungueltige Waermefallenmaske!", "Invalid heat trap mask!"); string ERRTEXTGLUED = M("Text ist verankert!","Text is glued!"); string ERRNOTABDEF = M("Tabellendefinition '%s' nicht gefunden!", "Table definition '%s' not found!"); string ERRNOMTEXT = M("Funktion fuer Mehrzeilentexte nicht unterstuetzt!", "Function not supported for multi line texts!"); string ERRCLIPEMPTY = M("Zwischenablage enthaelt keinen Text!", "Clipboard contains no text!"); string ERRNOGRP = M("Gruppe enthaelt keine Texte!", "No texts selected to group!"); string ERRNOPICK = M_ERRNOPICK(); string ERRINPVAL = M_ERRINPVAL(); // INI file parameter name definitions #define PAR_MAXEDIT "MTMAXEDIT_GED" // Max. multi line edit length #define PAR_TXTLSPC "TXTLSPACE_GED" // Text line relativ spacing #define PAR_MTEXTORIG "MTEXTORIG_STD" // Multi line text origin mode #define PAR_TEXTTABL "TEXTTABL_STD" // Text table definition // Global User Language program variables #define UL_FONTEDIT "fontedit" // ULP: Font editor utilities // Global definitions int MAXEDIT = bae_iniintval(PAR_MAXEDIT,60000); // Max. multi line edit length double LINESPC = bae_inidblval(PAR_TXTLSPC,1.0); // Text rel. line spacing int MTEXTORIG = bae_iniintval(PAR_MTEXTORIG,0); // Multi line text origin mode #define COLFIN 2 // Fade in color value double lastx,lasty /* Last vector coordinates */; struct tpoint { // Text point descriptor double x,y /* Point coordinates */; }; struct tpoint textdata[][] /* Text polygon data field */; int tpointcnt[] /* Text poly. points count field */; int tpolycnt = 0 /* Text polygon count */; int curlayer /* Current text layer */; string textstr /* Current text string */; int cnt = 0 /* Element count */; int ddbclass = bae_planddbclass() /* Layout plan DDB class */; static int WINDOWS = bae_swconfig(3)==BAE_WinStd || bae_swconfig(3)==BAE_WinPulldwn /* BAE Windows software flag */; // Main program void main() { index L_FIGURE fig /* Figure list index */; index L_TEXT text /* Text index */; string e_dis = "" /* Empty plan disable */; string t_dis = "," /* Text items disable */; string gt_dis = "," /* Group text items plan disable */; string lpd_dis = "" /* Layout/part/pad items disable */; int i /* Loop control variable */; // Check if call inside function check_fctactive(); // Test the plan class switch (ddbclass) { case DDBCLLAY : case DDBCLLPRT : case DDBCLLPAD : lpd_dis=","; break; case DDBCLLSTK : break; default : e_dis=lpd_dis=","; } // Check if element type scan if (bae_iniintval(PAR_METYPSCAN,1)==1 && !bae_peekiact()) { forall (text) { t_dis=""; forall (fig where fig.GROUP && fig.TYP==L_FIGTEXT) { gt_dis=""; break; } break; } } else { // Enable all menu items t_dis=gt_dis=""; } // Ask for text function type bae_defmenusel(-1); bae_promptdialog(UPRFCT); switch (bae_askmenu(16,t_dis+UPRFCT1,t_dis+UPRFCT2,t_dis+UPRFCT3, t_dis+UPRFCT4,t_dis+UPRFCT5,e_dis+UPRFCT6,t_dis+UPRFCT7,t_dis+UPRFCT8, t_dis+UPRFCT9,UPRFCT10,lpd_dis+UPRFCT11,lpd_dis+UPRFCT12, e_dis+UPRFCT13,t_dis+UPRFCT14,(WINDOWS ? t_dis : ",")+UPRFCT15, UPRABORT)) { // Set text size case 0 : settextsize(); break; // Set text layer case 1 : settextlayer(); break; // Set text plot width case 2 : bae_defmenusel(-1); bae_promptdialog(UPRDPMODE); switch (bae_askmenu(5,UPRDMODE1,UPRDMODE2, gt_dis+UPRDMODE3,gt_dis+UPRDMODE4,UPRABORT)) { // Change mouse selectable text line widths case 0 : settextpwidth(0); break; // Set mouse selectable text line widths case 1 : settextpwidth(1); break; // Set group text line widths case 2 : settextpwidth(2); break; // Scale group text line widths case 3 : settextpwidth(3); break; default : error_abort(); } break; // Text to trace/docarea conversion case 3 : bae_defmenusel(-1); bae_promptdialog(UPRGRP); switch (bae_askmenu(3,UPRGRP0,gt_dis+UPRGRP1,UPRABORT)) { case 0 : texttoarea(0); break; case 1 : texttoarea(1); break; } break; // Text to docline conversion case 4 : bae_defmenusel(-1); bae_promptdialog(UPRGRP); switch (bae_askmenu(3,UPRGRP0,gt_dis+UPRGRP1,UPRABORT)) { case 0 : texttoline(0); break; case 1 : texttoline(1); break; } break; // Arc text case 5 : arctext(); break; // Text upper case case 6 : textuppercase(); break; // Text lower case case 7 : textlowercase(); break; // Delete text case 8 : deletetext(); break; // Font editor case 9 : // Run the font editor utilities program runulprogexit(UL_FONTEDIT); // Set drill power layers case 10 : drlpowlay(); break; // Set drill heat trap mode case 11 : drlheattrap(); break; // Multi line text functions case 12 : bae_defmenusel(-1); bae_promptdialog(UPRMTEXTFCT); switch (bae_askmenu(12,UPRMFCT1,t_dis+UPRMFCT2,t_dis+UPRMFCT3, t_dis+UPRMFCT4,t_dis+UPRMFCT5,t_dis+UPRMFCT6,t_dis+UPRMFCT7, t_dis+UPRMFCT8,gt_dis+UPRMFCT9,t_dis+UPRMFCT10,UPRMFCT11, UPRABORT)) { // Add text case 0 : mtextadd(1); break; // Move text case 1 : mtextmove(); break; // Copy text case 2 : mtextcopy(); break; // Edit text case 3 : mtextedit(); break; // Delete text case 4 : mtextdelete(); break; // Set text size case 5 : mtextsize(); break; // Set text layer case 6 : mtextlayer(); break; // Select text case 7 : mtextselect(1); break; // Deselect text case 8 : mtextselect(0); break; // Toggle text case 9 : mtextselect(2); break; // Import table text case 10 : mtexttable(); break; default : error_abort(); } break; // Link to external file case 13 : linkfile(); break; // Place clipboard text case 14 : if (bae_getstrpar(10,textstr)!=0 || textstr=="") error(ERRCLIPEMPTY); // Check if text contains linefeeds for (i=strlen(textstr)-1;i>=0;i--) if (textstr[i]==0x0a) break; if (i>=0) { mtextadd(0); } else { ged_setintpar(35,1); bae_callmenu(MNU_GEDADDTEXT); ged_setintpar(35,0); } break; // Abort on default default : error_abort(); } } // Text functions void settextsize() /* // Set size of mouse-selectable texts */ { index L_FIGURE fig /* Figure list element */; double textsize /* Text size */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Get the text size textsize=baepar_dblval(LAYPAR_DEFTEXTSIZE); if (askdist(textsize,lay_defusrunit()?UPRTSIZEI:UPRTSIZEM,0) || textsize==0.0) // Invalid input value error(ERRINPVAL); // Loop while pick element found while (bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Set text size if (ged_elemsizechg(fig,textsize)) error(ERRCHANGE); // Perform screen redraw screenredraw(); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void settextlayer() /* // Change layer of mouse-selectable texts */ { index L_FIGURE fig /* Figure list element */; int layer /* New layer code */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Set default layer layer= ged_getlaydefmode()==2 ? ged_getlayerdefault() : ged_getpickpreflay(); // Select any layer if (bae_promptdialog(UPRTLAY),ged_asklayer(layer,7)) // Abort selected error_abort(); // Set new default layer ged_setlayerdefault(layer); layerfadein(layer,COLFIN,1); // Loop while pick element found while (bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Change layer if (ged_elemlaychg(fig,layer)) error(ERRCHANGE); // Perform screen redraw screenredraw(); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void settextpwidth(int opmode) /* // Set text plot width of mouse-selectable texts // Parameter : // int opmode : Operating mode */ { index L_FIGURE fig /* Figure list element */; double pwidth /* Plot width */; double scale = 1.0 /* Scale factor */; int cflag = 0 /* Change flag */; string msg /* Message string */; string rulel[] /* Rule list */; int rulen /* Rule count */; string mrulel[] /* Multiline text rule list */; int mrulen /* Multiline text rule count */; string mtextid = "" /* Multiline text ID */; string textid /* Current text ID */; double linespc /* Multiline text line spacing */; int col /* Multiline text column */; int row /* Multiline text row */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); switch (opmode) { // Change text line widths case 0 : // Loop while pick element found while ( bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { // Query the text line width if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_PLOTWIDTH,"?f",pwidth)<1) // Query last used plot width if (varget(VAR_PLOTW,pwidth)) // Use default path width ged_getpathwidth(pwidth,0.0); // Get plot width if (askdist(pwidth, lay_defusrunit()?UPRTPWIDI:UPRTPWIDM,0) || pwidth<0.0) error_abort(); if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Assign the plot width predicate rule rs_assfigdblpred(fig,RS_PLOTWIDTH,pwidth,0.0,""); // Query the multiline text status if (fig.RULEOBJID>=0 && lay_rulequery( RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",mtextid)>0 && mtextid!="") { // Get the rule count rulen=rs_getfigrules(fig,rulel); // Get the base rules mrulen=4; sprintf(mrulel[0],":%s:%s='%s';", RS_PCBSUBJ,RS_MTEXTID,mtextid); for (i=0;i=0 && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTID,"?s",textid)>0 && textid==mtextid) { // Get multiline text data if (lay_rulequery(RS_OCFIG,fig, RS_PCBSUBJ,RS_MTEXTCOL,"?d",col)<1 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)<1 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTLS,"?f",linespc)<1) continue; sprintf(mrulel[1],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(mrulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,row); sprintf(mrulel[3],":%s:%s=%.2f;", RS_PCBSUBJ,RS_MTEXTLS,linespc); if (lay_rulefigatt(fig,mrulel)) rs_error(-1); } } // Redraw the screen bae_callmenu(MNU_BAEREDISPL); } break; // Set text line widths case 1 : // Query last used plot width if (varget(VAR_PLOTW,pwidth)) // Use default path width ged_getpathwidth(pwidth,0.0); // Get plot width if (askdist(pwidth,lay_defusrunit()?UPRTPWIDI:UPRTPWIDM,0) || pwidth<0.0) error_abort(); // Loop while pick element found while ( bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Assign the plot width predicate rule rs_assfigdblpred(fig,RS_PLOTWIDTH,pwidth,0.0,""); // Query the multiline text status if (fig.RULEOBJID>=0 && lay_rulequery( RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",mtextid)>0 && mtextid!="") { // Get the rule count rulen=rs_getfigrules(fig,rulel); // Get the base rules mrulen=4; sprintf(mrulel[0],":%s:%s='%s';", RS_PCBSUBJ,RS_MTEXTID,mtextid); for (i=0;i=0 && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTID,"?s",textid)>0 && textid==mtextid) { // Get multiline text data if (lay_rulequery(RS_OCFIG,fig, RS_PCBSUBJ,RS_MTEXTCOL,"?d",col)<1 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)<1 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTLS,"?f",linespc)<1) continue; sprintf(mrulel[1],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(mrulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,row); sprintf(mrulel[3],":%s:%s=%.2f;", RS_PCBSUBJ,RS_MTEXTLS,linespc); if (lay_rulefigatt(fig,mrulel)) rs_error(-1); } } // Redraw the screen bae_callmenu(MNU_BAEREDISPL); } break; // Set group text line widths case 2 : // Query last used plot width if (varget(VAR_PLOTW,pwidth)) // Use default path width ged_getpathwidth(pwidth,0.0); // Get plot width if (askdist(pwidth,lay_defusrunit()?UPRTPWIDI:UPRTPWIDM,0) || pwidth<0.0) error_abort(); // Loop for all group elements of interest forall (fig where fig.GROUP && fig.TYP==L_FIGTEXT && !(fig.FIXED&2)) { // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Assign the plot width predicate rule rs_assfigdblpred(fig,RS_PLOTWIDTH,pwidth,0.0,""); } // Redraw the screen bae_callmenu(MNU_BAEREDISPL); break; // Scale group text line widths case 3 : // Get the scale factor if (askdbl(scale,UPRWSCALE,10)) error(ERRINPVAL); // Loop for all group elements of interest forall (fig where fig.GROUP && fig.TYP==L_FIGTEXT && !(fig.FIXED&2)) { // Query the polygon line width if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_PLOTWIDTH,"?f",pwidth)<1) pwidth=0.0; // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Assign the plot width predicate rule rs_assfigdblpred(fig,RS_PLOTWIDTH,scale*pwidth,0.0,""); } // Redraw the screen bae_callmenu(MNU_BAEREDISPL); break; } // Preserve width data for next call varset(VAR_PLOTW,pwidth); // Done bae_prtdialog(""); } void textuppercase() /* // Upper case mouse-selectable texts */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE nfig /* New figure list element */; string newstr /* New text string */; STRINGS rl /* Rule list */; // Loop while pick element found while (bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Get new text string strupper(newstr=fig.NAME); // Continue if no text string change request if (newstr==fig.NAME) continue; // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Store text with new string if (ged_storetext(newstr,fig.X,fig.Y,fig.ANGLE,fig.SIZE, fig.LAYER,fig.MIRROR|(fig.TEXT.MODE&TEXTEMSK))) errormsg(ERRTEXT,newstr); // Transfer rules if (fig.RULEOBJID>=0 && lay_lastfigelem(nfig)==0) { // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } // Delete old text element if (ged_delelem(fig)) errormsg(ERRDELETE,fig.NAME); // Perform screen redraw screenredraw(); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void textlowercase() /* // Lower case mouse-selectable texts */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE nfig /* New figure list element */; string newstr /* New text string */; STRINGS rl /* Rule list */; // Loop while pick element found while (bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Get lower case text string strlower(newstr=fig.NAME); // Continue if no text string change request if (newstr==fig.NAME) continue; // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Store text with new string if (ged_storetext(newstr,fig.X,fig.Y,fig.ANGLE,fig.SIZE, fig.LAYER,fig.MIRROR|(fig.TEXT.MODE&TEXTEMSK))) errormsg(ERRTEXT,newstr); // Transfer rules if (fig.RULEOBJID>=0 && lay_lastfigelem(nfig)==0) { // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } // Delete old text element if (ged_delelem(fig)) errormsg(ERRDELETE,fig.NAME); // Perform screen redraw screenredraw(); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void deletetext() /* // Delete mouse-selectable texts */ { index L_FIGURE fig /* Figure list element */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Loop while pick element found while (bae_promptdialog(UPRSELTEXT),ged_pickelem(fig,L_FIGTEXT)==0) { if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Delete element if (ged_delelem(fig)) errormsg(ERRDELETE,fig.NAME); // Perform screen redraw screenredraw(); cnt++; } // No pick if (cnt) bae_prtdialog(ERRNOPICK); else perror(ERRNOPICK); } void linkfile() /* // Set context function to external file call */ { index L_FIGURE fig /* Figure list element */; string extfile = "" /* External file */; string fext /* External file extension */; string predname /* Predicate name */; string menu /* Menu text */; string seq /* Command sequence */; string msg /* Message string */; char c /* Character buffer */; int i /* Loop control variable */; // Get text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the multiline text status if (fig.RULEOBJID>=0 && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s","")>0) error(ERRNOMTEXT); // Query current function sprintf(predname,RS_FCTSEQ,0); if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,predname,"?s",seq)<1) seq==""; // Check if context function defined if (seq!="") { // Check if not external file reference if (strmatch(seq,"#9049:\"$extappl:.*: *\"")==0) { // Query the menu text sprintf(predname,RS_FCTNAME,0); if (lay_rulequery( RS_OCFIG,fig,RS_PCBSUBJ,predname,"?s",menu)<1) menu=""; // Verify command replacement sprintf(msg,UPRFCTRPLC,bae_plainmenutext(menu)); if (bae_msgboxverify(msg,"")!=1) error_abort(); } else { // Extract file name from command sequence for (i=0;(c=seq[i])!='\0';i++) if (c==' ') { if (seq[i+1]=='\\') extfile=strextract( seq,i+3,strlen(seq)-4); else extfile=strextract( seq,i+1,strlen(seq)-2); break; } } } // Query the file name if (bae_askfilename(extfile,"",UPREXTFILE)) error_abort(); // Get the file name extension fext=strextract(extfile,strlen(convstring(extfile,0)),strlen(extfile)); // Assign the external file call context function sprintf(seq,"#9049:\"$extappl:%s: \\\"%s\\\"\"",fext,extfile); sprintf(predname,RS_FCTSEQ,0); rs_assfigstrpred(fig,predname,seq,"",""); sprintf(predname,RS_FCTNAME,0); rs_assfigstrpred(fig,predname,UPRFCT14,"",""); } // Arc text routines void arctext() /* // Arc text generation function */ { string textstr /* Text string */; double xc,yc /* Arc center coordinates */; double xs,ys /* Text start coordinates */; double xv,xvn,yv /* Text center vector */; double xt,xtn,yt /* Text base vector */; double rad /* Text arc radius */; double rotang /* Text vector rot. step angle */; double angsin,angcos /* Text vector rotation steps */; int rotflag /* Text rotation orientation */; double tsize /* Text size */; int autolaysel = 1 /* Auto. layer selection request */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Evaluate the layer default mode switch (ged_getlaydefmode()) { // Pick layer case 1 : curlayer=ged_getpickpreflay(); break; // Last used layer case 2 : curlayer=ged_getlayerdefault(); break; case 0 : default : // Select text layer curlayer=ged_getpickpreflay(); autolaysel=0; } // Check if layer selection if (!autolaysel) if (bae_promptdialog(UPRTLAY),ged_asklayer(curlayer,7)) error_abort(); // Set new default layer ged_setlayerdefault(curlayer); layerfadein(curlayer,COLFIN,1); // Get text size tsize=baepar_dblval(LAYPAR_DEFTEXTSIZE); if (askdist(tsize,lay_defusrunit()?UPRTSIZEI:UPRTSIZEM,0) || tsize<=0.0) error_abort(); // Get text string bae_setmousetext(""); if ((textstr=bae_readedittext(UPRTEXT,"",MAXTEXTLEN))=="" || textstr==UINPOPABORT) error_abort(); // Select arc center bae_promptdialog(UPRTCENTER); if ( bae_inpointmenu(bae_planwsnx(),bae_planwsny(),xc,yc,0,laydatafunc)) error_abort(); // Select text start coordinate if (bae_promptdialog(UPRTSTART),bae_inpoint(xc,yc,xs,ys,2)) error_abort(); if (xc==xs && yc==ys) error(ERRINPVAL); // Select rotation orientation if ((rotflag=bae_askmenu(3,UPRACLOCK,UPRCLOCK,UPRABORT))<0 || rotflag>1) error_abort(); // Get center vector xv=xs-xc; yv=ys-yc; // Get arc radius rad=sqrt(xv*xv+yv*yv); // Get rotation step angle rotang=tsize/(1.5*rad); if (rotflag) rotang*=(-1.0); // Get rotation angle data angsin=sin(rotang); angcos=cos(rotang); // Check if text base shift required if (!rotflag) { // Shift text center vector xv*=(rad+tsize)/rad; yv*=(rad+tsize)/rad; rad+=tsize; } // Rotate center vector by half angle xvn=cos(rotang/2.0)*xv-sin(rotang/2.0)*yv; yv=sin(rotang/2.0)*xv+cos(rotang/2.0)*yv; xv=xvn; // Get text base vector xt=(-tsize*yv/(3.0*rad)); yt=tsize*xv/(3.0*rad); // Check if text base rotation required if (!rotflag) { // Rotate text base by 180 degrees xt*=(-1.0); yt*=(-1.0); } // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Create text strings for (i=0;i=DOCLAYBASE) { // Documentary layer polytyp=L_POLYDOCAREA; polymode=1; } else { // Abort if invalid plan class if (ddbclass!=DDBCLLAY && ddbclass!=DDBCLLPRT) error(ERRPOLYLAY); // Check class layer combination if ((ddbclass==DDBCLLAY || ddbclass==DDBCLLPRT) && layer!=(-1) && layer!=(-5) && layer!=(-6)) // Set trace mode polymode=0; else { // Set polygon mode polymode=1; polytyp=L_POLYCOPPASS; } } // Save current state for undo if (cnt==0) bae_callmenu(MNU_BAESAVESTATE); // Clear last polygon coordinates lastx=(-1); lasty=(-1); // Vectorize the text characters if (lay_scanfelem(fig,0.0,0.0, 0.0,1,1,NULL,NULL,NULL,textfunc,NULL,NULL,NULL)!=0) error_scan(); // Loop for all text polygons for (i=0;i=DOCLAYBASE) { tfig=fig; convtexttoline(tfig); cnt++; } } else { // Loop while text pick element found while (bae_promptdialog(UPRSELTEXT), ged_pickelem(fig,L_FIGTEXT)==0) { convtexttoline(fig); cnt++; } } // No more pick if (cnt) { // Perform screen redraw screenredraw(); if (grpflag) { sprintf(msg,REPTEXTCHG,cnt); bae_prtdialog(msg); } else { bae_prtdialog(ERRNOPICK); } } else { perror(grpflag ? ERRNOGRP : ERRNOPICK); } } void convtexttoline(index L_FIGURE fig) /* // Convert text string to documentary line // Parameters : // index L_FIGURE fig : Figure list index */ { index L_FIGURE nfig /* New figure list index */; double width /* Text width */; int layer /* Text layer */; int i,j /* Loop control variables */; if (fig.FIXED&2) error(ERRTEXTGLUED); // Get the text characteristics layer=fig.LAYER; // Check layer if (layer=0;linen--) { col=0; text=strextract(lines[linen],0,MAXKEYLEN-1); while (strlen(text)>0) { // Store text with new string if (ged_storetext(text, bx+size*col*MAXKEYLEN*2.0/3.0,by,0.0,size,layer,0)) errormsg(ERRTEXT,text); // Attach rules if (lay_lastfigelem(fig)==0) { sprintf(rulel[0], ":%s:%s='%s';",RS_PCBSUBJ,RS_MTEXTID,textid); sprintf(rulel[1],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(rulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,linen); sprintf(rulel[3],":%s:%s=%.2f;", RS_PCBSUBJ,RS_MTEXTLS,LINESPC); if (lay_rulefigatt(fig,rulel)) rs_error(-1); } // Select to group if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); // Advance to next column col++; text=strextract( lines[linen],col*MAXKEYLEN,(col+1)*MAXKEYLEN-1); } // Advance to next line by+=size*LINESPC; } lay_lastfigelem(lfig); // Shift base point for upper left alignment by=bae_planwsny()+(MTEXTORIG ? (maxline*size*LINESPC) : 0.0); // Move the group anglock=bae_getanglelock(); bae_setanglelock(0); ged_getintpar(32,grpdisp); ged_setintpar(32,2); bae_clriactqueue(); bae_storemouseiact(1,bx,by,0,LMB); bae_callmenu(MNU_GEDMOVEGRP); if (bae_getanglelock()==0) bae_setanglelock(anglock); ged_setintpar(32,grpdisp); lay_lastfigelem(fig); // Reset the group or delete it if not placed bae_callmenu(fig==lfig ? MNU_GEDDELGRP : MNU_GEDGRPRESE); } void mtextmove() /* // Move a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; string movtextid /* Move text ID */; string textid /* Text ID */; double bx, by /* Text base line coordinates */; int anglock /* Old angle lock value */; int grpdisp /* Old group display mode */; int maxline = (-1) /* Max. text line */; int col /* Text column */; int row /* Text row */; double linespc /* Text line spacing */; double lsx, lsy /* Text line spacing vector */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",movtextid)<1 || movtextid=="") errormsg(ERRMTEXT,fig.NAME); if (fig.FIXED&2) error(ERRTEXTGLUED); // Set first guess for text base point bx=fig.X; by=fig.Y; // Get text line spacing if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTLS,"?f",linespc)<1) linespc=LINESPC; lsx=-sin(fig.ANGLE)*fig.SIZE*linespc; lsy=cos(fig.ANGLE)*fig.SIZE*linespc; // Reset the group bae_callmenu(MNU_GEDGRPRESE); // Scan all related multiline texts for movement forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==movtextid) { // Check if new best base point found if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTCOL,"?d",col)>0 && col==0 && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)>0 && row>maxline) { // Set text base point bx=fig.X; by=fig.Y; maxline=row; } // Select to group ged_elemgrpchg(fig,1); } if (MTEXTORIG) { // Shift base point for upper left alignment maxline++; bx+=maxline*lsx; by+=maxline*lsy; } // Move the group anglock=bae_getanglelock(); bae_setanglelock(0); ged_getintpar(32,grpdisp); ged_setintpar(32,2); bae_clriactqueue(); bae_storemouseiact(1,bx,by,0,LMB); bae_callmenu(MNU_GEDMOVEGRP); if (bae_getanglelock()==0) bae_setanglelock(anglock); ged_setintpar(32,grpdisp); // Reset the group bae_callmenu(MNU_GEDGRPRESE); } void mtextcopy() /* // Copy a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE ofig /* Old figure list element */; string cpytextid /* Copy text ID */; string newtextid /* New text ID */; string textid /* Text ID */; int anglock /* Old angle lock value */; int grpdisp /* Old group display mode */; int maxline = (-1) /* Max. text line */; int col /* Text column */; int row /* Text row */; double linespc /* Text line spacing */; double lsx, lsy /* Text line spacing vector */; double bx, by /* Text base line coordinates */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",cpytextid)<1 || cpytextid=="") errormsg(ERRMTEXT,fig.NAME); // Set first guess for text base point bx=fig.X; by=fig.Y; ofig=fig; // Get text line spacing if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTLS,"?f",linespc)<1) linespc=LINESPC; lsx=-sin(fig.ANGLE)*fig.SIZE*linespc; lsy=cos(fig.ANGLE)*fig.SIZE*linespc; // Reset the group bae_callmenu(MNU_GEDGRPRESE); // Scan all related multiline texts for copy forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==cpytextid) { // Check if new best base point found if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTCOL,"?d",col)>0 && col==0 && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)>0 && row>maxline) { // Set text base point bx=fig.X; by=fig.Y; maxline=row; } // Select to group ged_elemgrpchg(fig,1); } if (MTEXTORIG) { // Shift base point for upper left alignment maxline++; bx+=maxline*lsx; by+=maxline*lsy; } // Copy the group anglock=bae_getanglelock(); bae_setanglelock(0); ged_getintpar(32,grpdisp); ged_setintpar(32,2); bae_clriactqueue(); bae_storemouseiact(1,bx,by,0,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,11,LMB); bae_callmenu(MNU_GEDCOPYGRP); if (bae_getanglelock()==0) bae_setanglelock(anglock); ged_setintpar(32,grpdisp); // Check if copy aborted if (ofig.GROUP) { bae_callmenu(MNU_GEDGRPRESE); return; } newtextid=creatextid(); // Scan all new multiline texts for ID reassignment forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && fig.GROUP && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==cpytextid) rs_assfigstrpred(fig,RS_MTEXTID,newtextid,"",""); // Reset the group bae_callmenu(MNU_GEDGRPRESE); } void mtextedit() /* // Edit a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE dfig /* Delete figure list element */; STRINGS stext[] /* Scan text */; string text /* Text string */; string edttextid /* Edit text ID */; string textid /* Text ID */; STRINGS lines /* Text lines */; int linen /* Line count */; string rulename /* Rule name */; STRINGS mrulel /* Multiline text rule list */; int mrulen /* Multiline text rule count */; STRINGS rulel /* Text rules */; int rulen /* Text rule count */; double size /* Text size */; double angle /* Text angle */; int layer /* Text layer */; int mirr /* Text mirror mode */; double bx, by /* Text base line coordinates */; double lsx, lsy /* Text line spacing vector */; double lcx, lcy /* Text line column vector */; double linespc /* Text line spacing */; int maxline = (-1) /* Max. text line */; int maxcol = (-1) /* Max. text column */; int col /* Text column */; int row /* Text row */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",edttextid)<1 || edttextid=="") errormsg(ERRMTEXT,fig.NAME); if (fig.FIXED&2) error(ERRTEXTGLUED); // Set first guess for text base point bx=fig.X; by=fig.Y; size=fig.SIZE; layer=fig.LAYER; mirr=fig.MIRROR; angle=fig.ANGLE; // Get the old rule count rulen=rs_getfigrules(fig,rulel); // Get text line spacing if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTLS,"?f",linespc)<1) linespc=LINESPC; // Scan all related multiline texts for text retrival forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==edttextid) { // Get text position if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTCOL,"?d",col)<1) continue; if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)<1) continue; // Check if new best base point found if (col==0 && row>maxline) { // Set text base point bx=fig.X; by=fig.Y; maxline=row; } if (col>maxcol) maxcol=col; stext[col][row]=fig.NAME; } // Build the text edit string text=""; for (row=0;row<=maxline;row++) { for (col=0;col<=maxcol;col++) text+=stext[col][row]; text+="\n"; } // Edit the text if ((text=bae_readedittext(UPREDIT,text,MAXEDIT))=="" || text==UINPOPABORT) error_abort(); lsx=-sin(angle)*size*linespc; lsy=cos(angle)*size*linespc; lcx=cos(angle)*size*MAXKEYLEN*2.0/3.0; lcy=sin(angle)*size*MAXKEYLEN*2.0/3.0; if (mirr) { lcy=(-lcy); lsy=(-lsy); } // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Scan all related multiline texts for deletion forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==edttextid) { dfig=fig; ged_delelem(dfig); } // Split text into lines linen=splitstring(text,lines); if (MTEXTORIG) { // Shift base point for upper left alignment bx+=(maxline-linen+1)*lsx; by+=(maxline-linen+1)*lsy; } textid=creatextid(); // Get the base rules mrulen=4; sprintf(mrulel[0],":%s:%s='%s';",RS_PCBSUBJ,RS_MTEXTID,textid); sprintf(mrulel[3],":%s:%s=%.2f;",RS_PCBSUBJ,RS_MTEXTLS,linespc); for (i=0;i=0;linen--) { col=0; text=strextract(lines[linen],0,MAXKEYLEN-1); while (strlen(text)>0) { // Store text with new string if (ged_storetext(text, bx+col*lcx,by+col*lcy,angle,size,layer,mirr)) errormsg(ERRTEXT,text); // Attach rules if (lay_lastfigelem(fig)==0) { sprintf(mrulel[1],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(mrulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,linen); if (lay_rulefigatt(fig,mrulel)) rs_error(-1); } // Advance to next column col++; text=strextract( lines[linen],col*MAXKEYLEN,(col+1)*MAXKEYLEN-1); } // Advance to next line bx+=lsx; by+=lsy; } } void mtextdelete() /* // Delete a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE dfig /* Delete figure list element */; string deltextid /* Delete text ID */; string textid /* Text ID */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",deltextid)<1 || deltextid=="") errormsg(ERRMTEXT,fig.NAME); if (fig.FIXED&2) error(ERRTEXTGLUED); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Scan all related multiline texts for deletion forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==deltextid) { dfig=fig; ged_delelem(dfig); } } void mtextsize() /* // Set size of a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE dfig /* Delete figure list element */; STRINGS stext[] /* Scan text */; string seltextid /* Select text ID */; string textid /* Text ID */; STRINGS rulel /* Text rules */; double size /* Text size */; double oldsize /* Old text size */; double angle /* Text angle */; int layer /* Text layer */; int mirr /* Text mirror mode */; double bx, by /* Text base line coordinates */; double lsx, lsy /* Text line spacing vector */; double lcx, lcy /* Text line column vector */; int maxline = (-1) /* Max. text line */; int maxcol = (-1) /* Max. text column */; int col /* Text column */; int row /* Text row */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",seltextid)<1 || seltextid=="") errormsg(ERRMTEXT,fig.NAME); if (fig.FIXED&2) error(ERRTEXTGLUED); // Get the text size oldsize=size=fig.SIZE; if (askdist(size,lay_defusrunit()?UPRTSIZEI:UPRTSIZEM,0) || size==0.0) // Invalid input value error(ERRINPVAL); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Set first guess for text base point bx=fig.X; by=fig.Y; layer=fig.LAYER; mirr=fig.MIRROR; angle=fig.ANGLE; lsx=-sin(angle)*size*LINESPC; lsy=cos(angle)*size*LINESPC; lcx=cos(angle)*size*MAXKEYLEN*2.0/3.0; lcy=sin(angle)*size*MAXKEYLEN*2.0/3.0; // Scan all related multiline texts for text retrival forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==seltextid) { // Get text position if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTCOL,"?d",col)<1) continue; if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_MTEXTROW,"?d",row)<1) continue; // Check if new best base point found if (col==0 && row>maxline) { // Set text base point bx=fig.X; by=fig.Y; maxline=row; } if (col>maxcol) maxcol=col; stext[col][row]=fig.NAME; dfig=fig; ged_delelem(dfig); } if (MTEXTORIG) { // Shift base point for upper left alignment bx-=(maxline+1)*(size-oldsize)*lsx/size; by-=(maxline+1)*(size-oldsize)*lsy/size; } // Place the text lines textid=creatextid(); for (row=maxline;row>=0;row--) { for (col=0;col<=maxcol;col++) { if (strlen(stext[col][row])==0) continue; // Store text string if (ged_storetext(stext[col][row], bx+col*lcx,by+col*lcy,angle,size,layer,mirr)) errormsg(ERRTEXT,stext[col][row]); // Attach rules if (lay_lastfigelem(fig)==0) { sprintf(rulel[0], ":%s:%s='%s';",RS_PCBSUBJ,RS_MTEXTID,textid); sprintf(rulel[1], ":%s:%s=%d;",RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(rulel[2], ":%s:%s=%d;",RS_PCBSUBJ,RS_MTEXTROW,row); if (lay_rulefigatt(fig,rulel)) rs_error(-1); } } // Advance to next line bx+=lsx; by+=lsy; } } void mtextlayer() /* // Set layer of a mouse-selectable multi line text */ { index L_FIGURE fig /* Figure list element */; string seltextid /* Select text ID */; string textid /* Text ID */; int layer /* Text layer */; int cflag = 0 /* Change flag */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",seltextid)<1 || seltextid=="") errormsg(ERRMTEXT,fig.NAME); if (fig.FIXED&2) error(ERRTEXTGLUED); // Select any layer layer=fig.LAYER; if (bae_promptdialog(UPRTLAY),ged_asklayer(layer,7)) // Abort selected error_abort(); // Set new default layer ged_setlayerdefault(layer); layerfadein(layer,COLFIN,1); // Scan all related multiline texts for selection forall (fig where fig.RULEOBJID>=0 && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==seltextid) { // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } ged_elemlaychg(fig,layer); } } void mtextselect(int grpmode) /* // Group select a mouse-selectable multi line text // Parameters : // int grpmode : Group selection mode */ { index L_FIGURE fig /* Figure list element */; string seltextid /* Select text ID */; string textid /* Text ID */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Pick text bae_promptdialog(UPRSELTEXT); if (ged_pickelem(fig,L_FIGTEXT)) error(ERRNOPICK); // Query the text ID if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",seltextid)<1 || seltextid=="") errormsg(ERRMTEXT,fig.NAME); // Scan all related multiline texts for selection forall (fig where fig.RULEOBJID>=0 && fig.GROUP!=grpmode && fig.TYP==L_FIGTEXT && lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_MTEXTID,"?s",textid)>0 && textid==seltextid) ged_elemgrpchg(fig,grpmode); } void mtexttable() /* // Import a multi line text table */ { index L_FIGURE fig /* Figure list element */; struct tabdes { // Table entry descriptor int typ /* Table entry type */; int slen /* Table entry source length */; int dlen /* Table entry destination length */; int col /* Table entry destination column */; string sep /* Table entry seperator */; string patl[] /* Table entry pattern list */; string datl[] /* Table entry data list */; int datn /* Table entry data count */; } tdl[] /* Table entry list */; int tdn = 0 /* Table entry count */; int tidx /* Table index */; string table[][] /* Text table */; int tsl[] /* Table entry size list */; int skiplinen /* Header skip line count */; int linen = 0 /* Line count */; int col /* Text column */; int tcol = 0 /* Table column count */; int maxcol /* Maximum table column length */; STRINGS headl /* Header list */; int headn = 0 /* Header count */; STRINGS entryl /* Entry list */; int entryn = 0 /* Entry count */; string text /* Text string */; string entry /* Text table entry */; string varname /* Variable name */; string textid /* Text id */; string textcid /* Text column id */; double size /* Text size */; int layer /* Text layer */; double bx, by /* Text base line coordinates */; STRINGS rulel /* Text rules */; int anglock /* Old angle lock value */; int grpdisp /* Old group display mode */; STRINGS extlist = {bae_swversion(3)} /* File name extension list */; string seltabname /* Selection table name */; string readbuf /* Read buffer */; string ifname /* Input file name */; int ifh /* Input file handle */; int popcols /* Requested popup columns */; int i, j /* Loop control variables */; // Abort if invalid plan class if (ddbclass==DDBCLUNDEF) error_class(); // Set default layer layer= ged_getlaydefmode()==2 ? ged_getlayerdefault() : ged_getpickpreflay(); // Select any layer if (bae_promptdialog(UPRTLAY),ged_asklayer(layer,7)) // Abort selected error_abort(); // Set new default layer ged_setlayerdefault(layer); layerfadein(curlayer,COLFIN,1); // Get the text size size=baepar_dblval(LAYPAR_DEFTEXTSIZE); if (askdist(size,lay_defusrunit()?UPRTSIZEI:UPRTSIZEM,0) || size==0.0) // Invalid input value error(ERRINPVAL); // Select file to convert if ((ifname=askfile(UPRTABFILE,extlist,0))=="") error_abort(); for (entryn=0;entryn<1000;entryn++) if ((entryl[entryn]=bae_inistrval( bae_inifieldvarname(PAR_TEXTTABL,entryn,0),""))=="") break; // Check if table definitions found if (entryn==0) { // Create default table description skiplinen=0; for (tdn=0;tdn<20;tdn++) { tdl[tdn].typ=5; tdl[tdn].col=tdn; tdl[tdn].slen=0; tdl[tdn].dlen=0; tdl[tdn].sep=";"; tdl[tdn].datn=0; } tcol=tdn; } else { // Build the table definition menu headl[0]=REPTABLIST; headn=2; popcols=strlen(headl[0])+1; // Select group name bae_setintpar(16,3070); if ((seltabname=popupmenu(1,UPRSELTNAME, headl,headn,entryl,entryn,UINPOPABORT,0,1,1,headn+entryn+2, popcols,0,""))=="" || seltabname==UINPOPABORT) // Aborted error_abort(); for (tidx=0;tidx=entryn) errormsg(ERRNOTABDEF,seltabname); // Get the table definition skiplinen= bae_iniintval(bae_inifieldvarname(PAR_TEXTTABL,tidx,1),0); tidx++; for (tdn=0;tdn<1000;tdn++) { // Get table type sprintf(varname,"%s_%d_3_%d_1", PAR_TEXTTABL,tidx,tdn+1); if ((tdl[tdn].typ=bae_iniintval(varname,-1))==(-1)) // End of table definitions reached break; // Get table entry source length or seperator sprintf(varname,"%s_%d_3_%d_2", PAR_TEXTTABL,tidx,tdn+1); if ((tdl[tdn].typ&3)==1) { tdl[tdn].slen=0; tdl[tdn].sep=bae_inistrval(varname,";"); } else { tdl[tdn].slen=bae_iniintval(varname,1); tdl[tdn].sep=""; } // Get table entry destination length sprintf(varname,"%s_%d_3_%d_3", PAR_TEXTTABL,tidx,tdn+1); tdl[tdn].dlen=bae_iniintval(varname,0); // Get table entry destination column sprintf(varname,"%s_%d_3_%d_4", PAR_TEXTTABL,tidx,tdn+1); // Update max. column if ((tdl[tdn].col=bae_iniintval(varname,-1))>(tcol-1)) tcol=tdl[tdn].col+1; if (tdl[tdn].col>=0) tsl[tdl[tdn].col]=tdl[tdn].dlen; for (tdl[tdn].datn=0;tdl[tdn].datn<999;tdl[tdn].datn++) if ((tdl[tdn].typ&3)==2) { // Get table entry fix value list sprintf(varname,"%s_%d_3_%d_5_1_%d", PAR_TEXTTABL,tidx,tdn+1,tdl[tdn].datn+1); if ((tdl[tdn].datl[tdl[tdn].datn]= bae_inistrval(varname,UINPOPABORT))== UINPOPABORT) break; } else { // Get table entry value rep. pattern list sprintf(varname,"%s_%d_3_%d_5_%d_1", PAR_TEXTTABL,tidx,tdn+1,tdl[tdn].datn+1); if ((tdl[tdn].patl[tdl[tdn].datn]= bae_inistrval(varname,UINPOPABORT))== UINPOPABORT) break; sprintf(varname,"%s_%d_3_%d_5_%d_2", PAR_TEXTTABL,tidx,tdn+1,tdl[tdn].datn+1); tdl[tdn].datl[tdl[tdn].datn]= bae_inistrval(varname,""); } } } // Open the input file ifh=bae_fopen(ifname,0); // Skip file header for (i=0;i=0) table[tdl[i].col][linen]=entry; } linen++; } fclose(ifh); textid=creatextid(); layerfadein(layer,COLFIN,1); // Reset the group bae_callmenu(MNU_GEDGRPRESE); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Place the text lines bx=bae_planwsnx(); for (i=0;i=0;j--) { col=0; entry=table[i][j]; text=strextract(entry,0,MAXKEYLEN-1); if (strlen(text)>maxcol) maxcol=strlen(text); while (strlen(text)>0) { // Store text with new string if (ged_storetext(text, bx+size*col*MAXKEYLEN*2.0/3.0,by,0.0,size,layer,0)) errormsg(ERRTEXT,text); // Attach rules if (lay_lastfigelem(fig)==0) { sprintf(rulel[0], ":%s:%s='%s';",RS_PCBSUBJ,RS_MTEXTID,textcid); sprintf(rulel[1],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTCOL,col); sprintf(rulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,j); sprintf(rulel[3],":%s:%s=%.2f;", RS_PCBSUBJ,RS_MTEXTLS,LINESPC); if (lay_rulefigatt(fig,rulel)) rs_error(-1); } // Select to group if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); // Advance to next column col++; text=strextract( entry,col*MAXKEYLEN,(col+1)*MAXKEYLEN-1); } // Advance to next line by+=size*LINESPC; } bx+=size*(maxcol+1)*2.0/3.0; } // Shift base point for upper left alignment bx=bae_planwsnx(); by=bae_planwsny()+(MTEXTORIG ? (linen*size*LINESPC) : 0.0); // Move the group anglock=bae_getanglelock(); bae_setanglelock(0); ged_getintpar(32,grpdisp); ged_setintpar(32,2); bae_clriactqueue(); bae_storemouseiact(1,bx,by,0,LMB); bae_callmenu(MNU_GEDMOVEGRP); if (bae_getanglelock()==0) bae_setanglelock(anglock); ged_setintpar(32,grpdisp); // Reset the group bae_callmenu(MNU_GEDGRPRESE); } int splitstring(string s,STRINGS ssl) /* // Split string into lines // Return value : // number of substrings // Parameters : // string s : Input string // STRINGS ssl : Substring list */ { int ssn = 0 /* Substring count */; int sl = strlen(s) /* String length */; int pos1 = 1 /* String position buffer 1 */; int pos2 /* String position buffer 2 */; int i /* Loop controo variable */; // Repetively scan string while ((pos2=strscannext(s,"\n",pos1,1))pos1 ? strextract(s,pos1-1,pos2-2) : ""; // Update the scan start position pos1=pos2+1; } // Extract last substring if last char not delimiter if (pos1=0 && isspace(s[i])) ; // Extract and return substring return(i<0 ? "" : strextract(s,0,i)); } string strtrim(string s) /* // Trim string (skip leading and trailing white spaces) // Return value : // string without leading and trailing white spaces // Parameters : // string s : Input string */ { // Extract and return substring return(strrtrim(strltrim(s))); } // User Language program end