Index: tags/1.1.4/AUTHORS =================================================================== --- tags/1.1.4/AUTHORS (nonexistent) +++ tags/1.1.4/AUTHORS (revision 818) @@ -0,0 +1,3 @@ +Tibor 'Igor2' Palinkas + +Contact: http://igor2.repo.hu/contact.html Index: tags/1.1.4/COPYING =================================================================== --- tags/1.1.4/COPYING (nonexistent) +++ tags/1.1.4/COPYING (revision 818) @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. Index: tags/1.1.4/Changelog =================================================================== --- tags/1.1.4/Changelog (nonexistent) +++ tags/1.1.4/Changelog (revision 818) @@ -0,0 +1,349 @@ +camv-rnd 1.1.4 (r811) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Change: depend on librnd >=4.1.0 + + [core] + -Fix: typo in file name in error message when failing to load from CLI + -Del: local transformation matrix reverse functions in favor of librnd's + + [doc] + -Fix: we no longer depend on freetype + + [gui] + -Add: enable multiple selection in the file selection dialog for laoding multiple files at once + -Add: librnd-standard Export() action + + [sign] + -Add: new repo.hu crl for 2023 + +camv-rnd 1.1.3 (r785) +~~~~~~~~~~~~~~~~~~~~~ + [core] + -Fix: set arc object stroke shape for bbox calculation to avoid depending on uninitialized stack variable + -Fix: typo in file name in error message when failing to load from CLI + -Cleanup: remove static inline in favor of RND_INLINE so -Dinline can be removed from the command line on pre-c99 hosts + -Change: set y flip on design role, not cli role, to let actions override them more easily and make camv-rnd more consistent with pcb-rnd + -Add: menu/hotkey for all combinations of tab (using SwapSides() to flip the board) + + [gui] + -Fix: layersel respects sublayers when jumping over layers in layer moves + -Fix: off-by-one bug when moving layer-with-sublayers up in the GUI + -Fix: reset layer selector GUI struct for sublayers instead of just skipping them in the setup loop; moving sublayers around left stale gui structs behind, causing layer visibility icon mixup + -Add: SwapSides() action, mirroring pcb-rnd's; second argument, optional 'S', swaps (reverses) layer order + -Add: status line shows board flip state (whether display is from the top or bottom) + + [import_excellon] + -Add: metric file formats without digits should assume 4:4 for now + -Tune: change numeric format assumption for metric case to match the only sample we have + + [import_gerb] + -Fix: ignore long commands OF and SF (not supported) + -Fix: accept %AD* (empty aperture definition) + + [io_tedax] + -Fix: reverse polarity of layers on save so the file is ordered in the natural top->bottom order + + [menu] + -Add: {l o} for reverse layer ordering (in the view menu) + + +camv-rnd 1.1.2 (r746) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Add: link librnd's font lib + -Del: remove ./configure --fontdir (we have runtime font file path configuration instead) + -Fix: do not detect librnd from ./configure as ./configure depends on librnd + + [core] + -Fix: do not include 0;0 in layer bounding box, calculate the bbox only from objects + -Fix: make up an 1*1mm bbox for empty layers so they are easier to handle on the GUI + -Fix: initialize layer selection to -1 on start (no layer selected) + -Move: index of selected layer from the gui plugin to camv_design_t because some non-gui actions will need it + -Add: pass on and apply transformation matrix to object draw calls + -Add: initialize layer xform matrix to ident when the layer is created + -Add: draw code passes on layer xform matrix when enabled + -Add: RotateLayer() action (sets xform mx and enables it) + -Add: TranslateLayer() + -Add: ScaleLayer() + -Add: ResetLayer() action to reset the transformation matrix of a layer + -Add: layer append API option for layer groups: reverse order within the group but make sure the group is appended on top + -Add: group-load all layers specified on the command line so that order is preserved (from top to bottom) + -Add: sublayer loading API so that multi-layer files can bypass the layer grouping logic and keep their sublayers ordered + -Add: runtime configurable debug option for drawing object bounding boxes + -Add: accurate bbox calculation for arc objects + -Add: implement SaveTo() action (can save the whole design using the io plugin infra) + + [doc] + -Add: datasheet + -Add: mentions gmail is not supported + -Add: link in route-rnd and sch-rnd as part of Ringdove + -Add: install resources/ when installing doc + -Update: action reference for the new layer transformation actions + + [export_ps] + -Change: fill-page is default off for the ps export to get 1:1 prints + + [font] + -Change: replace ttf with embedded vector font (pcb-rnd's) + -Del: get rid of the freetype dependency and the ttf2bbox extern + -Del: font size is not set per text object, remove the associated field + -Add: center-align text: x;y coord should refer to bottom center point of the text object's bbox + + [gui] + -Add: Save() and SaveAs() actions + -Add: layersel debug option (compile time) + + [import_gerb] + -Fix: create sublayers using the sublayer API to preserve layer ordering + + [io_tedax] + -Fix: argument parsing: used the wrong number-of-arguments limit, leads to segfault if there are too many args + -Fix: increase number of args accepted to the theoretical limit the format permits + -Fix: preserve order of sublayers while loading a multi-polarity layer (using the sublayer append API) + -Add: implement save prio call for standard io hooks + + [menu] + -Add: save desgin that calls Save() + + [std_tools] + -Add: measurement tool: rotate text to line angle for better alignment + + +camv-rnd 1.1.1 (r662) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Fix: Makefile.depgen is generated and shouldn't be part of the repo + -Fix: .builtin.pups shouldn't be part of the repo, it's generated + -Change: switch over to librnd4 installation + -Cleanup: missing #include (exposed by hid.h not always included) + -Add: generate the usual set of installation path #defines in config.h + + [core] + -Fix: uninit librnd on exit so that cli history is saved and plugins are properly unloaded + -Cleanup: unregister plug_io_act.[ch] actions on exit + -Add: cli history config in the default conf file + -Add: emit RND_EVENT_LOAD_* events + + [dialogs] + -Fix: plugin should be in the gui package + -Fix: dialgos should be in camv-rnd-lib-gui package + -Fix: use the right config node path for setting CLI history size in preferences general tab + -Cleanup: rename pcb_dlg_pref_ to camv_dlg_pref_ to keep namespace clean + + [export_png] + -Cleanup: png export invocation example in help: replace .pcb to .gbr, that's the typical use case + -Fix: set expose context ->design before calling main expose + -Fix: don't use global desig when it is available from argument + -Del: don't define set_crosshair, use hid_nogui fallback + + [export_ps] + -Fix: set expose context ->design before calling main expose + + [export_svg] + -Fix: set expose context ->design before calling main expose + -Fix: don't use global desig when it is available from argument + + [gui] + -Fix: unregister actions on uninit + -Fix: unregister layersel events on uninit + + [import_gcode] + -Move: gcode-specific plugin settings into a local plugin conf + + [librnd4] + -Update: follow librd4 API changes + + [util] + -Del: deblist.sh from doc Makefile - not used by anything anymore + -Del: local implementation of awk_on_formats - use librnd's + -Add: import sign/ from librnd, for release verification + + +camv-rnd 1.1.0 (r558) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Fix: map_plugins target in the scconfig generated makefile + -Fix: internal menu's source name + -Fix: wrong path to the plugin dir in map_plugins + -Fix: CFLAGS for make dep so that librnd's src_3rd is found + -Fix: respect ./configure --confdir in Makefile.conf + -Fix: config.h uses configured prefix and config path + -Fix: sharedir and libdir need to end in /camv-rnd + -Fix: LIBDIR and SHAREDIR should include /camv-rnd in Makefile.conf + -Fix: use -L and -I to librnd when installed to non-standard path + + [core] + -Fix: --version should print the full version info all other Ringdove apps print, in the same format + -Fix: use rnd_hid_print_all_gui_plugins() for printing GUI HID plugins + -Fix: use rnd_render instead of rnd_gui for rendering so exports would work + -Fix: remember when io plugins are sorted + -Fix: make sure -lrnd-poly actually links in the poly lib (plugins depend on this) + -Add: export helper infra: default file name calculator + -Add: default export file name can be derived from the long name of the first layer + -Add: main_expose sets rnd_render to target hid so that lpr plugin's target exporter (ps) would be invoked correctly + + [doc] + -Add: comment on BSD make in INSTALL + -Add: install manual page + -Import: packager's doc from sch-rnd + -Import: appendix generation from pcb-rnd for acton refs, dialogs and formats + + [export_lpr] + -Add: standard lpr export for printing (imported from sch-rnd) + + [export_png] + -Add: plugin based on sch-rnd's implementation, using librnd pixmap export + + [export_ps] + -Add: standard ps/eps exporter (from sch-rnd) + + [export_svg] + -Add: standard svg export (from sch-rnd) + + [gui] + -Change: move the plugin in the lib-gui package (sch-rnd conventions) + -Add: standard print dialog from librnd + + [import_excellon] + -Cleanup: const correctness + + [import_gcode] + -Fix: extra cast to unsigned on the case values ot make sure the compiler doesn't think it's not integral + + [import_gerb] + -Fix: don't use fabs() on coords + -Fix: don't mix code and declarations (c89!) + + [menu] + -Add: ringdove-standard export and print menu + -Fix: print/export refers to drawing, not sheet (copy&paste error from sch-rnd) + + [scconfig] + -Import: from sch-rnd; switch over ./configure to use scconfig + + [util] + -Import: awk_on_formats script from sch-rnd (for the packager's doc script) + -Import: list dialogs devhelper from sch-rnd + +camv-rnd 1.0.3 (r453) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Fix: remove Makefile.dep dependencies on installed librnd headers - librnd is as external as libfreetype + + [core] + -Fix: Quit() performs clean HID-quit instead of raw exit(0) + -Del: message() based About() implementation + -Add: define layer selected event + -Add: right click context menu for layer properties + + [dialogs] + -Add: new plugin for hosting camv-rnd dialog boxes + -Add: about dialog + -Add: application-specific tab in preferences + -Add: layer (property) dialog: color set button and short name change + + [gui] + -Add: Layer(getidx) returns index of the currently selected layer (useful for scripting and cross-action calls) + -Add: layersel emits layer_selected event whenever layer selection changes + -Add: Layer(getlen) returns the number of layers + -Add: extend layer action: Layer(setcolor, #rrggbb) + -Add: layer action: Layer(rename, newname) changes the short name of a layer + -Add: layersel action: Layer(select, idx) will select the layer of the given index + + [import_excellon] + -Fix: in 'T' line: skip over S and F that may precede C + -Fix: both X and Y are optional in a move + -Fix: allow preserving last X or Y coordinate for partial lines that have only X or only Y + -Fix: don't treat the negative sign as part of the digits + -Add: accept header ,LZ and set leading-zero bit + -Add: a new, safer digit handler that can deal with both leading and trailing zeros + + [import_gerb] + -Fix: accept aperture re-definition (the reference gerber render does too), but throw a warning + -Fix: accept '*' terminated command sequence that doesn't have any actual drawing code but has state change 'set' commands (e.g. G01*) + -Fix: convert the error to warning that we get for empty command sequence (the reference viewer doesn't even mention it!) and expalain the situation better + -Add: number redundant error messages to ease debug + +camv-rnd 1.0.2 (r401) +~~~~~~~~~~~~~~~~~~~~~ + [core] + -Add: free font pixmap on text object removal + + [gui] + -Add: layersel: all visible/all invisible buttons + + [import_gcode] + -Cleanup: use TODO instead of (not portable) #warning + + [import_gerb] + -Fix: implicit decl + + [menu] + -Fix: {l r} wrong function arg: layer() has del, not remove + -Add: preferences dialog, bound to {i c p}, in file menu + +camv-rnd 1.0.1 (r375) +~~~~~~~~~~~~~~~~~~~~~ + [build] + -Fix: central Makefile uses the FORCE - required on lame, case insensitive filesystems where INSTALL is mistaken for install when running make install + -Fix: respect LIBARCHDIR in all Makefiles so that install works even if librnd used a non-default LIBRARCHDIR + -Fix: link librnd poly before hidlib - the poly lib depends on hidlib's heap + -Fix: make clean removes camv-rnd executable + -Add: make distclean + -Add: ./configure --help + + [conf] + -Fix: set default layer alpha to 75%; with 0 nothing would show + + [core] + -Fix: don't crash on empty layer name in layer-by-name lookup + -Fix: draw: main layer draw sequence so that layers are rendered properly on all gtk2_gdk, lesstif, gtk2_gl and gtk4_gl + -Tune: increase rtree stack size (temporary workaround) + -Cleanup: remove rnd_tool_gui_init() - it is implemented in librnd since 3.0.0 + -Add: if gtk2 HID is not available, also try gtk4 as fallback + + [doc] + -Fix: we do have a make install + -Fix: camv-rnd is not beta anymore + -Add: link edakrill from the -rnd box + -Add: INSTALL: freetype2 dep + -Change: bump required librnd version to 3.1.0 + + [gui] + -Fix: layersel: don't crash on non-existing layers + -Fix: remove the autoload line from pup because setting it 0 doesn't have the same effect and it is attempted to load too early + + [import_excellon] + -Fix: wrong pointer deref on checking for excellon end instruction + -Add: parse FMAT, remember file format version and throw warnings on inappropriate codes for a given version + -Add: ignore G90 (absolute coord mode), throw error on G91 (increment coord mode) + -Add: accept T0 for unloading the current tool (no tool selected) + + [import_gerb] + -Fix: "close-poly-on-move" shouldn't close non-existing polygon + -Fix: "close-poly-on-move" resets the poly after the move even if it doesn't need to be closed to make sure the starting coords are recorded properly + -Fix: pass down gerber ctx to aperture macro coord transformation as global unit will be needed for the conversion + -Fix: need to remember global unit setting for macro apertures + -Fix: expression parser: wrong order of operands generated for unary minus + -Fix: expression parser: typo caused syntax error or token-end not detected on '+' in numbers + -Fix: support for optional arguments in macro aperture drawing primitives + -Fix: step-rep: don't quit "looping" before the first iteration if the loop runs only once + -Fix: do not crash on missing arc aperture, just throw an error + -Fix: do not fetch the aperture while drawing poly contour + -Fix: generate 0 sized oblong as 1 nm thin + -Fix: make ignored case explicit (macro def shouldn't appear in render) + -Import: gerbv issue 57 test case for aperture macro out-of-bounds indexing + -Import: gerbv issue 56 test case for potential crash on invalid input + -Import: gerbv issue 30 test case to trigger a potential bug + -Add: parse fancy long command comments %TA, %TD, %TO, %TF (ignore them) + + [io_tedax] + -Fix: missing switch case on text objects (there is no persistent text, shouldn't be saved) + + +camv-rnd 1.0.0 (r299) +~~~~~~~~~~~~~~~~~~~~~ +Initial release. + + Index: tags/1.1.4/INSTALL =================================================================== --- tags/1.1.4/INSTALL (nonexistent) +++ tags/1.1.4/INSTALL (revision 818) @@ -0,0 +1,41 @@ +Standard installation procedure for camv-rnd. + +1. install librnd >=4.1.0 + + Either from a source release at http://www.repo.hu/projects/librnd + or from VCS: svn checkout svn://svn.repo.hu/librnd/trunk + + ./configure + make + make install + + While configuring, make sure to include some GUI HIDs, e.g. hid_gtk2_gdk + or hid_gtk2_gl. + + You also need to install lib freetype2 and have pkg-config available for it. + + Note: the build may fail with BSD make. + +2. run ./configure + + If librnd is installed in /usr or /usr/local, it will be picked up + automatically. Else set env var LIBRND_PREFIX to librnd's installation + prefix path before running ./configure. + + Optional ./configure arguments: + --prefix=/foo/bar change camv-rnd installation prefix + --confdir=/foo/etc/camv-rnd change config dir used in install + --CFLAGS=-Wall -g3 inject CFLAGS in c compile cmd line + --LDFLAGS=-Wfoo -Wbar inject LDFLAGS in link cmd line + + Result of the configuration can be observed in Makefile.conf and + config.h. + +3. make + +4. make install + +5. optional: running from source (works without installation) + +cd src && ./camv-rnd filename1 filename2 ... + Index: tags/1.1.4/Makefile =================================================================== --- tags/1.1.4/Makefile (nonexistent) +++ tags/1.1.4/Makefile (revision 818) @@ -0,0 +1,25 @@ +all: FORCE + cd src && $(MAKE) all +# do not compile doc/ (all rendered files are commited - Ringdove policy) + +install: FORCE + cd src && $(MAKE) install + cd doc && $(MAKE) install + +linstall: FORCE + cd src && $(MAKE) linstall + cd doc && $(MAKE) linstall + +uninstall: FORCE + cd src && $(MAKE) uninstall + cd doc && $(MAKE) uninstall + +clean: FORCE + cd src && $(MAKE) clean +# do not clean doc/ (all rendered files are commited - Ringdove policy) + +distclean: FORCE + cd src && $(MAKE) distclean +# do not clean doc/ (all rendered files are commited - Ringdove policy) + +FORCE: Index: tags/1.1.4/Makefile.conf.in =================================================================== --- tags/1.1.4/Makefile.conf.in (nonexistent) +++ tags/1.1.4/Makefile.conf.in (revision 818) @@ -0,0 +1,45 @@ +put /tmpasm/OFS { } +put /local/camv/CFLAGS_GENERIC cc/cflags +append /local/camv/CFLAGS_GENERIC cc/fpic +append /local/camv/CFLAGS_GENERIC ?/local/camv/cflags_profile +put /local/camv/CFLAGS /local/camv/CFLAGS_GENERIC +uniq /local/camv/CFLAGS +uniq /local/camv/CFLAGS_GENERIC + +print [@# generated by ./configure, do not modify + +# Compatibility with autotools on DESTDIR - Debian really wants this +# Still keep install_root as well, because that has a better name +Install_root=$(install_root)$(DESTDIR) + +# prefix is +PREFIX=@/local/prefix@ +BINDIR=$(install_root)$(DESTDIR)$(PREFIX)/bin +CONFDIR=$(install_root)$(DESTDIR)@/local/confdir@ +LIBDIR=$(install_root)$(DESTDIR)$(PREFIX)/lib/camv-rnd +SHAREDIR=$(install_root)$(DESTDIR)$(PREFIX)/share/camv-rnd +DOCDIR=$(install_root)$(DESTDIR)$(PREFIX)/share/doc/camv-rnd + +RM=@/host/fstools/rm@ +CP=@/host/fstools/cp@ +LN=@/host/fstools/ln@ +MKDIR=@/host/fstools/mkdir@ +SCCBOX=$(ROOT)/scconfig/sccbox +EXE=@/target/sys/ext_exe@ +CAMV_RND_HOST_CC=@/host/cc/cc@ +CAMV_RND_VER=@/local/version@ + +CFG_CFLAGS=@?cc/argstd/std_c99@ @/local/camv/CFLAGS@ +CFG_C89FLAGS=@/local/camv/c89flags@ @/local/camv/CFLAGS@ +CFG_LDFLAGS= + +# The installation directoried to be used from within binaries (with +# install_root/DESTDIR removed) +LIBDIR_INSTALLED=@/local/prefix@/lib/camv-rnd + +# Where librnd is installed, full path to the .mak file to auto-setup +LIBRND_PREFIX=@/local/camv/librnd_prefix@ +LIBRND_MAK=$(LIBRND_PREFIX)/share/librnd4/librnd.mak +include $(LIBRND_MAK) + +@] Index: tags/1.1.4/README =================================================================== --- tags/1.1.4/README (nonexistent) +++ tags/1.1.4/README (revision 818) @@ -0,0 +1,6 @@ +camv-rnd is a viewer of (mostly PCB-related) CAM file formats, such +as gerber (layer image), excellon (drill files) and gcode. + +camv-rnd is part of the Ringdove suite. + +For more info, see doc/index.html Index: tags/1.1.4/Release_notes =================================================================== --- tags/1.1.4/Release_notes (nonexistent) +++ tags/1.1.4/Release_notes (revision 818) @@ -0,0 +1,9 @@ +camv-rnd 1.1.4 +~~~~~~~~~~~~~~ + +This release features multiple file name selection in the open dialog and +an Export() action similar to pcb-rnd's. + +From this version, camv-rnd depends on librnd >=4.1.0 + + Index: tags/1.1.4/config.h.in =================================================================== --- tags/1.1.4/config.h.in (nonexistent) +++ tags/1.1.4/config.h.in (revision 818) @@ -0,0 +1,58 @@ +if ?cc/inline +then + put /local/cc/inline {inline} +end + +print [@ +#ifndef CAMV_CENTRAL_CONFIG_H +#define CAMV_CENTRAL_CONFIG_H + +#define RND_APP_PREFIX(x) camv_ ## x + +/****************************************************************************/ +/* Paths */ +@] + +switch sys/class + case {win32} + print [@ +#define CAMV_PREFIX rnd_w32_root +#define CAMVSHAREDIR rnd_w32_sharedir +#define CAMVLIBDIR rnd_w32_libdir +#define BINDIR rnd_w32_bindir +#define CAMVCONFDIR @/local/confdir@ +@] + end; + default + print [@ +#define CAMV_PREFIX "@/local/prefix@" +#define CAMVSHAREDIR CAMV_PREFIX "/share/camv-rnd" +#define CAMVLIBDIR CAMV_PREFIX "/lib/camv-rnd" +#define BINDIR CAMV_PREFIX "/bin" +#define CAMVCONFDIR "@/local/confdir@" +@] + end; +end; + +print [@ + +/* Relative path from bindir to exec_prefix */ +#define BINDIR_TO_EXECPREFIX ".." + +#include + +/* the dot-dir: where to save user config under ther user's home; it's used + as ~/DOT_CAMV_RND/ */ +#define DOT_CAMV_RND "@/local/camv/dot_camv_rnd@" + +#define LIBRND_PREFIX "/usr/local" +#define CONFDIR "@/local/confdir@" +#define LIBDIR "@/local/prefix@/lib/camv-rnd" +#define SHAREDIR "@/local/prefix@/share/camv-rnd" +#define CAMV_VERS "@/local/version@" +#define CAMV_REV "@/local/revision@" + + + +#endif +@] Index: tags/1.1.4/config.sh.in =================================================================== --- tags/1.1.4/config.sh.in (nonexistent) +++ tags/1.1.4/config.sh.in (revision 818) @@ -0,0 +1,6 @@ +print [@ +# *** Autogenerated by scconfig *** DO NOT EDIT *** +# camv-rnd config for shell scripts +librnd_root=@/local/camv/librnd_prefix@ +librnd_libdir=$librnd_root/lib/librnd4 +@] Index: tags/1.1.4/configure =================================================================== --- tags/1.1.4/configure (nonexistent) +++ tags/1.1.4/configure (revision 818) @@ -0,0 +1,40 @@ +#!/bin/sh + +if test -z "$LIBRND_PREFIX" +then + for P in /usr/local /opt/librnd /usr $HOME/usr + do + if test -e "$P/include/librnd4/librnd/core/config.h" + then + LIBRND_PREFIX="$P" + break + fi + done +fi + + +case "$LIBRND_PREFIX" in + "") + echo " + +ERROR: Can not find librnd (required for camv-rnd). + +If librnd is not installed, please read INSTALL for details. + +If librnd is installed at a non-standard prefix, please read +doc/INSTALL.librnd.txt and set LIBRND_PREFIX accordingly +(e.g. export LIBRND_PREFIX=/home/foo/sw/librnd) before running ./configure + +" >&2 + exit 1 + ;; + /usr/include) ;; + /usr/local/include) ;; + *) LIBRND_EXTRA_INCLUDE="$LIBRND_PREFIX/include/librnd4" +esac + + +cd scconfig +make "LIBRND_PREFIX=$LIBRND_PREFIX" LIBRND_EXTRA_INCLUDE="-I$LIBRND_EXTRA_INCLUDE" && \ +./configure prefix/libs/sul/librnd-3rd=$LIBRND_PREFIX "$@" + Property changes on: tags/1.1.4/configure ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/doc/Autostyle.html =================================================================== --- tags/1.1.4/doc/Autostyle.html (nonexistent) +++ tags/1.1.4/doc/Autostyle.html (revision 818) @@ -0,0 +1,14 @@ + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ Index: tags/1.1.4/doc/Autostyle.sh =================================================================== --- tags/1.1.4/doc/Autostyle.sh (nonexistent) +++ tags/1.1.4/doc/Autostyle.sh (revision 818) @@ -0,0 +1,77 @@ +#!/bin/sh + +autostyle() +{ + awk -v "template=$1" -v "root=$ROOT" ' + BEGIN { + while((getline < template) > 0) { + if (parse_auto(RES, $0)) { + if (RES["action"] == "begin") + curr = RES["ID"] + else + reset_curr = 1 + } + if (curr != "") + AUTO[curr] = AUTO[curr] var_subs($0) "\n" + if (reset_curr) { + curr = "" + reset_curr = 0 + } + } + } + + function var_subs(s) + { + gsub("[$]ROOT[$]", root, s) + return s + } + + function parse_auto(RES, line ,tmp) + { + if (!(line ~ ".*", "", line) + line = tolower(line) + tmp = line + sub("[ \t].*$", "", tmp) + RES["ID"] = tmp + tmp = line + sub("^[^ \t]*[ \t]*", "", tmp) + RES["action"] = tmp + return 1 + } + + { + if (parse_auto(RES, $0)) { + if (RES["action"] == "begin") + skip = 1 + else if (RES["action"] == "end") { + printf("%s", AUTO[RES["ID"]]) + skip = 0 + } + next + } + } + + (!skip) { print $0 } + + ' +} + +for html in $* +do + case $html in + Autostyle.html) ;; + *) + mv $html $html.tmp + autostyle "Autostyle.html" < $html.tmp > $html + if test $? = 0 + then + rm $html.tmp + else + echo "Failed on $html, keeping the original version." + mv $html.tmp $html + fi + esac +done Property changes on: tags/1.1.4/doc/Autostyle.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/doc/Makefile =================================================================== --- tags/1.1.4/doc/Makefile (nonexistent) +++ tags/1.1.4/doc/Makefile (revision 818) @@ -0,0 +1,57 @@ +MENU_RES=../src/menu.lht +# append this when plugins start to have menu files: ../src_plugins/*/*-menu.lht + +ROOT=.. +LIBARCHDIR=$(LIBRND_LIBARCHDIR) + +all: user/keys.html user/keytree.svg user/keytree.txt + ROOT="" ./Autostyle.sh *.html + +include ../Makefile.conf +include $(LIBRND_MAK) + +SCCBOX = $(LIBRND_PREFIX)/$(LIBARCHDIR)/librnd4/scconfig/sccbox + +user/keytree.svg: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --dot user/node_names.txt $(MENU_RES) > user/keytree.dot + dot -Tsvg < user/keytree.dot >user/keytree.svg + +user/keytree.txt: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --lst $(MENU_RES) > user/keytree.txt + + +user/keys.html: $(MENU_RES) $(KEYLIST) + $(KEYLIST) $(MENU_RES) > user/keys.html + +install_main: + $(SCCBOX) $(HOW) *.html TODO $(DOCDIR)/ + +install: + $(SCCBOX) mkdir -p "$(DOCDIR)" + cd user && $(MAKE) install + cd man && $(MAKE) install + cd developer && $(MAKE) install + cd resources && $(MAKE) install + $(MAKE) install_main HOW="install -f -d" + +linstall: + cd user && $(MAKE) linstall + cd man && $(MAKE) linstall + cd developer && $(MAKE) linstall + cd resources && $(MAKE) linstall + $(MAKE) install_main HOW="install -f -l -d" + +uninstall: + cd user && $(MAKE) uninstall + cd man && $(MAKE) uninstall + cd developer && $(MAKE) uninstall + cd resources && $(MAKE) uninstall + $(MAKE) install_main HOW="install -f -u -d" + +clean: + cd user && $(MAKE) clean + cd developer && $(MAKE) clean + +distclean: + cd user && $(MAKE) distclean + cd developer && $(MAKE) distclean Index: tags/1.1.4/doc/TODO =================================================================== --- tags/1.1.4/doc/TODO (nonexistent) +++ tags/1.1.4/doc/TODO (revision 818) @@ -0,0 +1,14 @@ +0. old reports waiting for ACK ============================================= + +1. For the upcoming release ========================================================================= + +2. For later releases =============================================================================== + - BUG: import_gcode doesn't compile with old gcc 4.6 (acer laptop) due to macro magic + - BUG: {i c p}, tree tab, layer colors, [4], edit at user role: saves a conf array with empty nodes up to [4] [report: Alain] + - DOC: pool node on how to create and load a "project file" action script that loads specific file names and assigns colors to the resulting layers [report: Alain] + - FEATURE: draw.c: [report: cuvoodoo] + - add popup menu+dialog for the transformations per layer + - replace byacc with byaccic: + - gcode + - gerber + Index: tags/1.1.4/doc/contact.html =================================================================== --- tags/1.1.4/doc/contact.html (nonexistent) +++ tags/1.1.4/doc/contact.html (revision 818) @@ -0,0 +1,56 @@ + + + + + camv-rnd - contact + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +

camv-rnd - contact

+ +

Contact the project

+

+Please subscribe to the mailing list by sending "subscribe" to +pcb-rnd list.repo.hu (does not work with gmail) +or join IRC for + live chat (CET daytime) with other users +and developers. + +

Contact the lead developer

+

+Join IRC for live chat (CET daytime) and +look for Igor2. +

+Via email: pcbrnd igor2.repo.hu (does not work with gmail). + + +
+

+PRIVACY NOTICE: +

+This email address is provided only for personal use, exclusively for +topics directly related to the pcb-rnd and camv-rnd project. +

+Do NOT copy this email address to +software packages, documentation, etc. Permission is NOT granted +for collecting this email address in any list of email addresses. +Since this email address is a personal address, the + +GDPR applies while you are handling it. +

+ + Index: tags/1.1.4/doc/datasheet.html =================================================================== --- tags/1.1.4/doc/datasheet.html (nonexistent) +++ tags/1.1.4/doc/datasheet.html (revision 818) @@ -0,0 +1,73 @@ + + + + camv-rnd - datasheet + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +

camv-rnd - datasheet

+ + + + + + + + + +
rendering characteristics + multiple layers +
different file format per layer possible +
per layer color +
flexible layer ordering +
translucent layers (when OpenGL rendering is used) +
GUI features + measure tool + +
File formats:
Import images +
+ + excellon drill files
g-code CNC program
gerber layer image
tEDAx camv-rnd layer + + +
File formats:
Export misc +
+ + printer (using ps)
png
ps
eps
svg
tEDAx camv-rnd layer + + + + + + +
UI options + gtk2, gtk4, lesstif (motif), batch (automated processing) +
configurable menus, keyboard and mouse actions +
scripting + embedded scripting using fungw (awk, python, lua, tcl, ruby, perl, javascript, lisp, shell, pascal, BASIC) + +
misc + flexible configuration system +
support for small screen (800x600) +
strong support for automated processing +
modularity (most code implemented in plugins) +
slim code, reduced external dependency, portability +
+ + + Index: tags/1.1.4/doc/datasheet.sh =================================================================== --- tags/1.1.4/doc/datasheet.sh (nonexistent) +++ tags/1.1.4/doc/datasheet.sh (revision 818) @@ -0,0 +1,24 @@ +#!/bin/sh + +ROOT=.. + +if test -z "$LIBRND_LIBDIR" +then + # when not run from the Makefile + LIBRND_LIBDIR=`cd developer/packaging && make -f librnd_root.mk libdir` +fi + +proot=$ROOT/src_plugins +. $LIBRND_LIBDIR/devhelpers/awk_on_formats.sh + +awk_on_formats ' +($1 == " + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +
+ +

camv-rnd documentation

+ + + + + Index: tags/1.1.4/doc/faq.html =================================================================== --- tags/1.1.4/doc/faq.html (nonexistent) +++ tags/1.1.4/doc/faq.html (revision 818) @@ -0,0 +1,59 @@ + + + + camv-rnd - FAQ + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +
+ +

camv-rnd FAQ

+ +

1. File formats

+ +

1.1. g-code for laser cutter

+

+A common g-code laser cut dialect uses M3 and M5 for turning the laser +on/off. For other machines (mills, routers), these codes control the +spindle. The default configuration assumes the latter. If you have a file +for laser and it doesn't use G0 for travel but relies on M3/M5 for +laser on/off, you need to switch the config bit at plugins/import_gcode/laser +before loading the file. +

+On GUI, tick in the corresponding laser menu in File/Loader configuration. +

+On the command line, use -c plugins/import_gcode/laser=1. +

+If you more often use g-code files for laser than not, you can make this the +default value in your user config. + +

2. build/install

+ +

2.1. Error while loading shared libraries

+

+If the above error message appears and lists librnd-* libs when executing +camv-rnd, that means your operating system's dynamic loader is unable to +find There are trhee common reasons for this: +

    +
  • camv-rnd is installed from binary and librnd is not installed. Install librnd. +
  • librnd is installed from source to standard installation prefix (/usr or /usr/local); on some systems ldconfig needs to be run after installing new libs from source so that the system's dynamic loader can find the new .so files +
  • librnd is installed from source to a non-standard installation prefix, e.g. installation in home directory or /opt; see INSTALL.librnd.txt for the extra steps this setup requires +
+ + + Index: tags/1.1.4/doc/index.html =================================================================== --- tags/1.1.4/doc/index.html (nonexistent) +++ tags/1.1.4/doc/index.html (revision 818) @@ -0,0 +1,94 @@ + + + + camv-rnd - main + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +
+ + +
+

Summary

+ +
+
[camv-rnd logo]camv-rnd
+
+ is a free/open source, small, flexible viewer for PCB-related CAM file formats +

supports gerber, excellon, g-code +

imports/exports multiple file formats +

is part of the Ringdove EDA suite +

is part of the coralEDA ecosystem. + +

Version Control svn://svn.repo.hu/camv-rnd/trunk +
Download source releases +
Comments, feedback, patches live chat with the developer
or use the mailing list of pcb-rnd + +
Key features + viewer for Printed Circuit Board related CAM files +
scriptable in 10+ different scripting languages +
small +
fits well in a UNIXy workflow +
supports CLI and server applications +
active development, frequent releases +
friendly and efficient developer and user community + +
Supported platforms + +
+ Linux desktop (various distributions, from source) +
+
+
+
+
OpenBSD (Likely: any BSD not older than 25 years) +
(Likely: any 90's or newer UNIX system with motif) +
Screen resolution as small as 800x600 +
GUI options: motif/lesstif, gtk-gdk, gtk-gl +
+ + screenshot of camv-rnd running on Debian GNU/Linux +
+
+ + +
+ + + +

What is -rnd?

+ + +
+ +

+

RiNgDove is an EDA suite that includes: +

a schematics editor: sch-rnd +

a PCB editor: pcb-rnd +

a PCB autorouter: route-rnd +

a CAM viewer: camv-rnd +

a software lib: librnd +

or all in one: suite +

  +

user contributed addons: edakrill +

+ +
+ + + Index: tags/1.1.4/doc/irc.html =================================================================== --- tags/1.1.4/doc/irc.html (nonexistent) +++ tags/1.1.4/doc/irc.html (revision 818) @@ -0,0 +1,46 @@ + + + + camv-rnd - IRC + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +

Live support via IRC (chat)

+
Irc server: repo.hu       Port: 6667       Channel: #pcb-rnd +
  +

I'm normally online as Igor2 between 5:00 CET and 19:00 CET; on Sunday there's an AFK-window between 11:00 CET and 16:00 CET. If I don't answer in a few minutes I'm probably away doing something, please be patient; say hi before you type your long question so you see if I'm available. +


+

+Below is an iframe of +kiwiirc irc client configured with the above settings. If it doesn't +work, please visit their page and +try to manually configure it, it's just 4 fields. +

+Using the web client: you should change your nickname (or using the +/nick myname command if you are already connected); there's no password +or registration or channel key or ssl of any form. Your real IP won't be +shown on the IRC network (check kiwiirc's page about their privacy +policy). +

+Connecting with the web client may take some time, give it a minute. +


+ + + + + Index: tags/1.1.4/doc/license.html =================================================================== --- tags/1.1.4/doc/license.html (nonexistent) +++ tags/1.1.4/doc/license.html (revision 818) @@ -0,0 +1,46 @@ + + + + camv-rnd - license + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +

camv-rnd - license

+Camv-rnd is a Free Software, Open source, under the terms of GPL version 2. +

+Camv-rnd incorporates a few mini-libs with various, GPL-compatible licenses, mostly +BSD, MIT and public domain - the official Debian package has a great index of these. +

+For users: the resulting software is distributable under the GNU GPL version 2 +(or later versions), the usual GPL terms and conditions apply. +

+Contribution: by contributing, you agree to submit patches that are conforming +to the license terms (e.g. don't copy random code from other projects). We +are keeping track of copyright: each contributor holds the copyright for and +is responsible for their part. Contributors agree to license their contribution +under the same term as the subproject they are adding to, which is typically +GPL2+ for core and plugins and utilities. +

+Re-licensing under different conditions: camv-rnd's GPL2+ allows the user +to upgrade to GPL3 or later versions of the GPL (as long as new versions +don't contradict with the license of the mini-libs). It is possible to request +relicensing but has to be backed up by a real strong reasoning. +Same rules apply for mini-libs. + + + Index: tags/1.1.4/doc/man/Makefile =================================================================== --- tags/1.1.4/doc/man/Makefile (nonexistent) +++ tags/1.1.4/doc/man/Makefile (revision 818) @@ -0,0 +1,66 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from $(ROOT)/Makefile.conf which is scconfig generated +ROOT=../.. + +include $(ROOT)/Makefile.conf +MAN1DIR=$(install_root)$(DESTDIR)$(PREFIX)/share/man/man1 +LIBARCHDIR=$(LIBRND_LIBARCHDIR) +SCCBOX = $(LIBRND_PREFIX)/$(LIBARCHDIR)/librnd4/scconfig/sccbox + +IN=camv-rnd.1.mml +OUT_HTML = camv-rnd.1.html +OUT_MAN1 = camv-rnd.1 +OUT_LINT = camv-rnd.1.lint + +OUTPUT = $(OUT_HTML) $(OUT_MAN1) index.html +MML = /usr/bin/mml + +all: $(OUTPUT) + +lint: $(OUT_LINT) + +.SUFFIXES: .html .mml .lint + +.mml.html: .mml_linkmap + $(MML) -i copyright.mml -f html $< > $@ + +.mml: + $(MML) -i copyright.mml -f man $< > $@ + +.mml_linkmap: + $(MML) -i copyright.mml -f linkmap $(IN) > $@ + +index.html: $(IN) + @echo '' > $@ + @echo 'man page index - camv-rnd

    ' >> $@ + $(MML) -i copyright.mml -f indexhtml $(IN) >> $@ + @echo "
" >> $@ + +clean: + +distclean: + +genclean: + rm $(OUTPUT) 2>/dev/null ; true + +.mml.lint: + $(MML) -i copyright.mml -f lint $< + +install_dir: + $(SCCBOX) mkdir -p "$(MAN1DIR)" + +install_all: + $(SCCBOX) $(HOW) "camv-rnd.1" "$(MAN1DIR)/camv-rnd.1" + +install: + $(MAKE) install_dir + $(MAKE) install_all HOW="install -f" + +linstall: + $(MAKE) install_dir + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + + Index: tags/1.1.4/doc/man/README =================================================================== --- tags/1.1.4/doc/man/README (nonexistent) +++ tags/1.1.4/doc/man/README (revision 818) @@ -0,0 +1,10 @@ +Manual pages are written in the manual markup format and are compiled into +manual and html using mml. Do not edit the generated manual or html pages. + +The generated files are commited in the repository so dependencies are not +required for casual users to build the project. + +The required tools and dependencies are: + svn://repo.hu/libmawk/trunk + svn://repo.hu/web3.0/trunk + svn://repo.hu/shscripts/trunk/manmarkup Index: tags/1.1.4/doc/man/camv-rnd.1 =================================================================== --- tags/1.1.4/doc/man/camv-rnd.1 (nonexistent) +++ tags/1.1.4/doc/man/camv-rnd.1 (revision 818) @@ -0,0 +1,45 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2021 Tibor 'Igor2' Palinkas +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License along +.\" with this program; if not, write to the Free Software Foundation, Inc., +.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +.\" +.\" Contact: pcb-rnd-man[removethis]@igor2.repo.hu +.TH camv-rnd 1 2019-10-01 "" "pcb-rnd manual" +.SH NAME +camv-rnd - viewer for PCB related CAM files +.SH SYNPOSIS +.nf +.sp +\fBcamv-rnd [\fIoptions\fB] [\fIinputfile1\fB [\fIinputfile2...\fB]] +.fi +.SH DECSRIPTION + +.BR camv-rnd +loads and displays zero or more files in multiple layers. Files can be specified on the command line or can be loaded using the menu once camv-rnd is running. +.PP + +.SH OPTIONS + + +.TP + +.B --gui \fIhid\fR +Use the \fIhid\fR plugin for the "gui" frontend. Common choices are "gtk2_gdk" or "lesstif" for graphical user interfaces and "batch" for a headless command-line interface (or automated batch processing). +.TP + +.B -c \fIpath=val\fR +Set a config node in role CFR_CLI. The path of the node is \fIpath\fR (e.g. editor/grid) and the new value is \fIval\fR (e.g. 5mm). +.PP + Index: tags/1.1.4/doc/man/camv-rnd.1.html =================================================================== --- tags/1.1.4/doc/man/camv-rnd.1.html (nonexistent) +++ tags/1.1.4/doc/man/camv-rnd.1.html (revision 818) @@ -0,0 +1,82 @@ + + + +camv-rnd - pcb-rnd manual + + + + +
camv-rnd 1 + 2019-10-01 + pcb-rnd manual +
+ + + +

NAME

+
+camv-rnd - viewer for PCB related CAM files +
+ +

SYNPOSIS

+
+

+camv-rnd [options] [inputfile1 [inputfile2...]] + + + +

+ +

DESCRIPTION

+
+camv-rnd loads and displays zero or more files in multiple layers. Files can be specified on the command line or can be loaded using the menu once camv-rnd is running. +

+ + +

+ + +

OPTIONS

+
+ + + + + + + +
--gui hid + Use the hid plugin for the "gui" frontend. Common choices are "gtk2_gdk" or "lesstif" for graphical user interfaces and "batch" for a headless command-line interface (or automated batch processing). +
-c path=val + Set a config node in role CFR_CLI. The path of the node is path (e.g. editor/grid) and the new value is val (e.g. 5mm). +
+
+

+ + +
camv-rnd 1 + 2019-10-01 + pcb-rnd manual +
+ + + Index: tags/1.1.4/doc/man/camv-rnd.1.mml =================================================================== --- tags/1.1.4/doc/man/camv-rnd.1.mml (nonexistent) +++ tags/1.1.4/doc/man/camv-rnd.1.mml (revision 818) @@ -0,0 +1,33 @@ +camv-rnd +1 +2019-10-01 + + camv-rnd - viewer for PCB related CAM files + camv-rnd [options] [inputfile1 [inputfile2...]] + + +camv-rnd loads and displays zero or more files in multiple +layers. Files can be specified on the command line or can be loaded using +the menu once camv-rnd is running. +

+ + + + + + + --gui hid + Use the hid plugin for the "gui" frontend. Common + choices are "gtk2_gdk" or "lesstif" for graphical user interfaces + and "batch" for a headless command-line interface (or automated + batch processing). + + + -c path=val + Set a config node in role CFR_CLI. The path of the node is + path (e.g. editor/grid) and the new value is + val (e.g. 5mm). + + + + Index: tags/1.1.4/doc/man/copyright.mml =================================================================== --- tags/1.1.4/doc/man/copyright.mml (nonexistent) +++ tags/1.1.4/doc/man/copyright.mml (revision 818) @@ -0,0 +1,21 @@ + +pcb-rnd - manual\n +Copyright (C) 2021 Tibor 'Igor2' Palinkas\n +\n +This program is free software; you can redistribute it and/or modify\n +it under the terms of the GNU General Public License as published by\n +the Free Software Foundation; either version 2 of the License, or\n +(at your option) any later version.\n +\n +This program is distributed in the hope that it will be useful,\n +but WITHOUT ANY WARRANTY; without even the implied warranty of\n +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n +GNU General Public License for more details.\n +\n +You should have received a copy of the GNU General Public License along\n +with this program; if not, write to the Free Software Foundation, Inc.,\n +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n +\n +Contact: pcb-rnd-man[removethis]@igor2.repo.hu + +pcb-rnd manual Index: tags/1.1.4/doc/man/index.html =================================================================== --- tags/1.1.4/doc/man/index.html (nonexistent) +++ tags/1.1.4/doc/man/index.html (revision 818) @@ -0,0 +1,4 @@ + +man page index - camv-rnd

    +
  • camv-rnd (1) -- camv-rnd - viewer for PCB related CAM files +
Index: tags/1.1.4/doc/news.html =================================================================== --- tags/1.1.4/doc/news.html (nonexistent) +++ tags/1.1.4/doc/news.html (revision 818) @@ -0,0 +1,91 @@ + + + + camv-rnd - news + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +
+ +

News

+ +
+ + + + + + + + + +
+ 2023-09-27 +
+ release: 1.1.3 +
+ Release 1.1.3 available: minor bugfixes, SwapSides {tab} + +
+ 2023-05-24 +
+ release: 1.1.2 +
+ Release 1.1.2 available: use librnd font rendfering engine instead of ttf, bugfixes + +
+ 2023-02-08 +
+ release: 1.1.1 +
+ Release 1.1.1 available: librnd API upgrades; requires librnd 4.0.0 + +
+ 2022-11-16 +
+ release: 1.1.0 +
+ Release 1.1.0 available: major feature release (scconfig, export plugins) + +
+ 2022-06-24 +
+ release: 1.0.3 +
+ Release 1.0.3 available: minor bugfixes, layer name/color change from GUI + +
+ 2022-03-16 +
+ release: 1.0.2 +
+ Release 1.0.2 available: minor bugfixes + +
+ 2021-06-14 +
+ librnd3 +
+ Converted the project to use librnd 3.x.x + + +
+
+ + + Index: tags/1.1.4/doc/resources/Makefile =================================================================== --- tags/1.1.4/doc/resources/Makefile (nonexistent) +++ tags/1.1.4/doc/resources/Makefile (revision 818) @@ -0,0 +1,24 @@ +ROOT=../.. +RESDIR=$(DOCDIR)/resources + +all: + +install_all: + $(SCCBOX) mkdir -p $(RESDIR) + $(SCCBOX) $(HOW) -d *.png *.svg $(RESDIR) + +install: + $(MAKE) install_all HOW="install -f -d" + +linstall: + $(MAKE) install_all HOW="install -f -l -d" + +uninstall: + $(MAKE) install_all HOW="install -u" + +clean: + +distclean: + + +include $(ROOT)/Makefile.conf Index: tags/1.1.4/doc/resources/at.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.1.4/doc/resources/at.png =================================================================== --- tags/1.1.4/doc/resources/at.png (nonexistent) +++ tags/1.1.4/doc/resources/at.png (revision 818) Property changes on: tags/1.1.4/doc/resources/at.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.1.4/doc/resources/logo128.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.1.4/doc/resources/logo128.png =================================================================== --- tags/1.1.4/doc/resources/logo128.png (nonexistent) +++ tags/1.1.4/doc/resources/logo128.png (revision 818) Property changes on: tags/1.1.4/doc/resources/logo128.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.1.4/doc/resources/logo16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.1.4/doc/resources/logo16.png =================================================================== --- tags/1.1.4/doc/resources/logo16.png (nonexistent) +++ tags/1.1.4/doc/resources/logo16.png (revision 818) Property changes on: tags/1.1.4/doc/resources/logo16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.1.4/doc/resources/logo32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.1.4/doc/resources/logo32.png =================================================================== --- tags/1.1.4/doc/resources/logo32.png (nonexistent) +++ tags/1.1.4/doc/resources/logo32.png (revision 818) Property changes on: tags/1.1.4/doc/resources/logo32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.1.4/doc/resources/logo64.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/1.1.4/doc/resources/logo64.png =================================================================== --- tags/1.1.4/doc/resources/logo64.png (nonexistent) +++ tags/1.1.4/doc/resources/logo64.png (revision 818) Property changes on: tags/1.1.4/doc/resources/logo64.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/1.1.4/doc/resources/logo_big.svg =================================================================== --- tags/1.1.4/doc/resources/logo_big.svg (nonexistent) +++ tags/1.1.4/doc/resources/logo_big.svg (revision 818) @@ -0,0 +1,987 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.1.4/doc/resources/logo_small.svg =================================================================== --- tags/1.1.4/doc/resources/logo_small.svg (nonexistent) +++ tags/1.1.4/doc/resources/logo_small.svg (revision 818) @@ -0,0 +1,1038 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.1.4/doc/resources/ringdove2.svg =================================================================== --- tags/1.1.4/doc/resources/ringdove2.svg (nonexistent) +++ tags/1.1.4/doc/resources/ringdove2.svg (revision 818) @@ -0,0 +1,144 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/1.1.4/doc/support.html =================================================================== --- tags/1.1.4/doc/support.html (nonexistent) +++ tags/1.1.4/doc/support.html (revision 818) @@ -0,0 +1,63 @@ + + + + camv-rnd - support + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + camv-rnd [camv-rnd logo] +
+ + +
+ +

camv-rnd support

+ +

Get support

+ +Option 1: subscribe to the pcb-rnd mailing list: pcb-rnd list.repo.hu (send +a mail with subject: subscribe). We usually reply there within 24 hours. + (Archives) +

+Option 2: real-time chat with the developers and hard core users: IRC ; please pick a meaningful nickname, join, say +hi, state your question and be patient; someone will react in at most +3..4 hours. If nobody reacts but you see traffic, repeat your question. +Leaving there an idler client is okay. +

+The generic rule is that over whatever channel you can reach us, that's +also the right place to ask questions about camv-rnd and we will answer there. +Currently these are the channels where we can be reached: +

+ +
type address +
public mailing list send subscribe to pcb-rnd list.repo.hu +
public IRC channel irc.repo.hu:6667 #pcb-rnd +
private email Igor2's email address +
private IRC Igor2 on irc.repo.hu +
+ +

Give support

+Option 1: if you are experienced with pcb-rnd or electronics: subscribe to +the mailing list, join IRC, try to provide help for +newbies. +

+Option 2: subscribe to the mailing list, offer your help. +

+Option 3: consider donating a small amount , +e.g. $5 or $10. Donations are transformed into developer hours put in the project. + + + + Index: tags/1.1.4/doc/user/09_appendix/action_details.html =================================================================== --- tags/1.1.4/doc/user/09_appendix/action_details.html (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/action_details.html (revision 818) @@ -0,0 +1,891 @@ + + + + + camv-rnd user manual - action details + + + + +

camv-rnd actions (details)

+ + + +

layer

+
+

+ +
Syntax summary:n/a +
Help text:n/a +
Registered by:n/a +
+

+Change a layer property or layer ordering, depending on the argument: +

+ Up or down moves the layer one slot up or down in layer ordering. Top or bottom moves the layer to the top or bottom in layer ordering. Layers are rendered from bottom to top: layers higher on the list will render over layers lower on the list. This matters especially if appearance/layer_alpha is 1 and layers are solid with no translucencly. +

+ Del removes the currently selected layer. +

+ getidx returns the index of the currently selected layer as an integer; getlen returns the number of layers as an integer. These are useful for user scripting. +

+ setcolor and rename changes the color or name of the currently selected layer (new color or name supplied as a second argument). +

+ all-visible and all-invisible changes visibility of all layers. +

+

librnd actions (common to Ringdove)

+ + + +

AddTimer

+
+

+ +
Syntax summary: +AddTimer(action, period, [repeat], [userdata]) +
Help text: +Add a new timer +
Registered by: +script plugin +
+

+This action is intended for scripts to create async timers. + +Note: + + timers do not work with the batch HID (no callback issued ever). +

+ Creates a timer that executes an +action + (by name) periodically. +Period + is a real number specified in seconds. Internal timer resolution is in the order of 0.1 second. +

+ If +repeat + is not specified or is less than 1, the timer is repeated indefinitely. If the optional +userdata + string is specified, it is also passed to the action. +

+ The +action + is specified only by a name, call arguments are always the following: +

    + +
  • + now: the current UNIX time in a floating point number +
  • + integer: count back remaining number of calls, including the current call; 1 means this was the last call; 0 means infinite number of calls will follow +
  • + +userdata + or empty string +
+ +

+ +Action + shall return integer 0 on success. If the action does not exist or returns anything else, the timer is uninstalled. +

+ There can be any number of timers in parallel. +

+ +

AnyLoad

+
+

+ +
Syntax summary: +AnyLoad([path]) +
Help text: +Load "anything" from path (or offer a file selectio dialog if no path specified) +
Registered by:n/a +
+

+Loads an anyload.lht file or any lihata document that can be handled by the anyload system (mostly settings and setting-like states, e.g. config, vendor drill map, DRC and user scripts). +

+ When called without arguments a file selection dialog is popped up for selecting the file to load. +

+ More info on this mechanism in the + + knowledge pool node of anyload. + + +

+ +

Benchmark

+
+

+ +
Syntax summary: +Benchmark() +
Help text: +Benchmark the GUI speed. +
Registered by:n/a +
+

+This action is used to speed-test the GUI rendering. It redraws the current screen as many times as possible in ten seconds. It reports the amount of time needed to draw the screen once, in average. +

+ +

Center

+
+

+ +
Syntax summary: +Center() +
Help text: +Moves the pointer to the center of the window. +
Registered by: +lib_hid_common plugin +
+

+Move the pointer to the center of the window, but only if it's currently within the window already. +

+ +

Cursor

+
+

+ +
Syntax summary: +Cursor(Type,DeltaUp,DeltaRight,Units) +
Help text: +Move the cursor. +
Registered by:n/a +
+

+This action moves the mouse cursor. Unlike other actions which take coordinates, this action's coordinates are always relative to the user's view of the board. Thus, a positive +DeltaUp + may move the cursor away from the board origin if the board is inverted (flipped, looked from the bottom). +

+ +Type + is one of + +Pan + + or + +Warp + +. + +Pan + + causes the viewport to move such that the crosshair is under the mouse cursor. + +Warp + + causes the mouse cursor to move to be above the crosshair. +

+ +Units + can be one of the following: +

+ + + + + + + + + + + +
+mil +
+mm +
+The cursor is moved by that amount, in board units. +
+grid + +The cursor is moved by that many grid points. +
+view + +The values are percentages of the viewport's view. Thus, a pan of + +100 + + would scroll the viewport by exactly the width of the current view. +
+board + + The values are percentages of the board size. Thus, a move of + +50,50 + + moves you halfway across the board. +
+ +

+ +

dowindows

+
+

+ +
Syntax summary:n/a +
Help text:n/a +
Registered by:n/a +
+

+Argument: +

+ + + + + + + + + + + + + + + + + +
+ 1 +
+ Layout +
+ Open the layout window. Since the layout window is always shown anyway, this has no effect. +
+ 2 +
+ Library +
+ Open the library window. +
+ 3 +
+ Log +
+ Open the log window. +
+ 4 +
+ Netlist +
+ Open the netlist window. +
+ 5 +
+ Preferences +
+ Open the preferences window. +
+ 6 +
+ DRC +
+ Open the DRC violations window. +
+ 7 +
+ Search +
+ Open the advanced search window. +
+ +

+ +

GetXY

+
+

+ +
Syntax summary: +GetXY([message, [x|y]]) +
Help text: +Get a coordinate. If x or y specified, the return value of the action is the x or y coordinate. +
Registered by:n/a +
+

+Prompts the user for a coordinate, if one is not already selected. +

+ +

ListScripts

+
+

+ +
Syntax summary: +ListScripts([pat]) +
Help text: +List fungw scripts, optionally filtered wiht regex pat. +
Registered by: +script plugin +
+

+Print one line in the log for each currently loaded script. If +pat + is specified, filter the list using +pat + as a case sensitive + +extended regex + + on script ID, file name and language (list only scripts that match with any of these fields). +

+ +

LiveScript

+
+

+ +
Syntax summary: +LiveScript([new], [name]) +LiveScript(load|save, name, [filame]) +LiveScript(run|stop|rerun|undo, name) +
Help text: +Manage a live script +
Registered by: +script plugin +
+

+The first argument determines what operation the action performs and how subsequent arguments are interpreted: +

+ + + + + + + + + + + + + + + + + +
+ new, [name] + + Create a new live script and open a new live script dialog. + +name + + is an unique live script name that identifies the window. If not specified, "default" is used" +
+ load, name, [filename] + + Replace the script source in the LiveScript window identified by + +name + + with the content loaded from a file. If + +filename + + is not specified, open a file selector dialog. +
+ save, name, [filename] + + Save the script source in the LiveScript window identified by + +name + + to a file. If + +filename + + is not specified, open a file selector dialog. +
+ run, name + + Run the script in the LiveScript window identified by + +name + +. +
+ stop, name + + Stop the script in the LiveScript window identified by + +name + +, if ti is running in persistent mode. +
+ undo, name + + Undo the "init changes" of the script in the LiveScript window identified by + +name + +. Init changes are those board changes the script has done while running its initialization section. Live script undo is possible only if there was no user edit after the script finished. +
+ rerun, name + + Stop, undo and run the script in the LiveScript window identified by + +name + +. +
+ +

+ +

LoadScript

+
+

+ +
Syntax summary: +LoadScript(id, filename, [language]) +
Help text: +Load a fungw script +
Registered by: +script plugin +
+

+ +id + is an arbitrary string assigned by the user. +id + must be unique per application session per script and may contain alphanumeric characters and undescrore. +

+ +fn + is the file name of the script, which is a path. Librnd does not do any search, it only opens the path as specified. +

+ +lang + is the scripting language, as in + +fungw plugin name + +. When not specified, the code makes a guess (based on the file name). +

+ +

Message

+
+

+ +
Syntax summary: +message([ERROR|WARNING|INFO|DEBUG,] message) +
Help text: +Writes a message to the log window. +
Registered by:n/a +
+

+This action displays a message to the log window. This action is primarily provided for use by scripts and external programs which may interface with the application. If multiple arguments are given, each one is sent to the log window followed by a newline. +

+ If there are 2 or more arguments and the first argument matches, in a case sensitive manner, one of the below keywords, the message is registered on the specified error level. Else the PCB_MSG_INFO error level is used. +

+ + + + + + + + + + + + + +
+first argument + +erro level +
+ERROR + + PCB_MSG_ERROR +
+WARNING + + PCB_MSG_WARNING +
+INFO + + PCB_MSG_INFO +
+DEBUG + + PCB_MSG_DEBUG +
+ +

+ +

onliner

+
+

+ +
Syntax summary:n/a +
Help text:n/a +
Registered by:n/a +
+

+The +oneliner + action is designed for quick execution of short, trivial scripts, such as a for loop for repeating an action. It supports any scripting language currently availabel through fungw. Each oneliner is an independent script context - variables, functions and other global states do not persist. +

+ This group of actions offers three forms: +

    + +
  • + +oneliner +( +lang +, +script +) - execute the script in the language specified +
  • + lang(script) - shorthand for the above +
  • + lang - switch the command line interpreter to execute one-liners in the given language, until /exit +
+ +

+ For example, a simple calculation using awk can be done in three ways: +

    + +
  • + + +oneliner(awk, 'print 42*3') + + +
  • + + +awk('print 42*3') + + +
  • + + +awk + +, then + +print 42*3 + +, then + +/exit + + +
+ +
+ +

Pan

+
+

+ +
Syntax summary: +Pan(Mode) +
Help text: +Start or stop panning (Mode = 1 to start, 0 to stop) +
Registered by: +lib_hid_common plugin +
+

+Start or stop panning. To start call with Mode = 1, to stop call with Mode = 0. +

+ +

Print

+
+

+ +
Syntax summary: +Print() +
Help text: +Present the print export dialog for printing the layout from the GUI. +
Registered by:n/a +
+

+Open an export dialog listing all printing plugins, prompt the user for their options, and print the layout. +

+ Available only with GUI HIDs: it's merely a graphical shorthand that in turn calls the export plugin for printing. +

+ +

PromptFor

+
+

+ +
Syntax summary: +PromptFor([message[,default[,title]]]) +
Help text: +Prompt for a string. Returns the string (or NULL on cancel) +
Registered by:n/a +
+

+UI-independent way of asking the user for a string. When GUI is available, it is a dialog box, else it's console input. Return value, unlike with other actions, is a string. The return value is NULL on cancel. +

+ +

ReloadScript

+
+

+ +
Syntax summary: +ReloadScript(id) +
Help text: +Reload a fungw script +
Registered by: +script plugin +
+

+ +id + is the same that was specified for +loadscript +. If loading the new verison of the script fails, +id + is released (can be reused for a new LoadScript). +

+ +

ScriptCookie

+
+

+ +
Syntax summary: +ScriptCookie() +
Help text: +Return a cookie specific to the current script instance during script initialization +
Registered by: +script plugin +
+

+The script: +

    + +
  • + may call ScriptCookie() + +during script initialization + + and save the resulting cookie string +
  • + may use the cookie string to register to core application or librnd infrastructure that requires cookie, such as +createmenu + +
  • + can depend on the application to call any unregistering associated with this specific cookie atomatically after script unload ( +preunload +). +
+ +

+ The function can not be called outside of script initialization. The cookie string can be used any time between script load and script unload. +

+ +

ScriptPersistency

+
+

+ +
Syntax summary: +ScriptPersistency(read|remove) +
Help text: +Read or remove script persistency data savd on preunload +
Registered by: +script plugin +
+

+When a script is unloaded, its action +preunload + is called. The return value is saved as script persistent data. When the script is loaded again later, it can use +scriptpersistency +( +read +) to read the data saved. +

+ +scriptpersistency +( +remove +) deletes the data from disk. +

+ Note: the data is per script id, not per script file name. +

+ +

Scroll

+
+

+ +
Syntax summary: +Scroll(up|down|left|right, [pixels]) +
Help text: +Scroll the viewport. +
Registered by: +lib_hid_common plugin +
+

+Arguments: +

+ + + + + + + +
+ up|down|left|right + + Specifies the direction to scroll +
+ pix + + Optional. Specifies how many pixels to scroll by. If not specified: default pix is 100. +
+ +

+ +

SetGridOffs

+
+

+ +
Syntax summary: +SetGridOffs(x_offs, y_offs) +
Help text: +Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units. +
Registered by:n/a +
+

+Changes the grid offset to relative or absolute x_offs and y_offs. For non-zero values always use units, e.g. SetGrifOffs(0.5mm, 0.1mm). +

+ The final grid offset alues will be scaled down so they are always between 0 and the current grid size. For example with a 25 mil grid, a value of 7mil will be taken as 7mil offset, but a value of 27 mil will be taken as a 2mil offset. +

+ If an offset starts with + or -, it is taken as relative, which means it is added to the current offset value. +

+ +

SetUnits

+
+

+ +
Syntax summary: +SetUnits(mm|mil) +
Help text: +Set the default measurement units. +
Registered by:n/a +
+

+ + + + + + + +
+ mil + + Sets the display units to mils (1/1000 inch). +
+ mm + + Sets the display units to millimeters. +
+ +

+ +

Tool

+
+

+ +
Syntax summary: +Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer) +Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via) +Tool(Press|Release|Cancel|Stroke) +Tool(Save|Restore) +
Help text: +Change or use the tool mode. +
Registered by:n/a +
+

+Selects the tool or changes tool related global states. +

+ + + + + + + + + + + + + + + + + + + +
+ <app-specific-tool-name> + + Select the indicated tool. Tool names depend on the application and plugins loaded. For example in pcb-rnd one of the valid tool names is + +Line + +. +
+ Press + + Called when you press the mouse button, or move the mouse. +
+ Release + + Called when you release the mouse button. +
+ Cancel + + Cancels any pending tool activity, allowing you to restart elsewhere. For example, this allows you to start a new line rather than attach a line to the previous line. +
+ Escape + + Similar to Cancel but calling this action a second time will return to the Arrow tool. +
+ Stroke + + If librnd was built with libstroke, this invokes the stroke input method. If not, this will restart a drawing mode if you were drawing, else it will select objects. +
+ Save + + Remembers the current tool. +
+ Restore + + Restores the tool to the last saved tool. +
+ +

+ +

UnloadScript

+
+

+ +
Syntax summary: +UnloadScript(id) +
Help text: +Unload a fungw script +
Registered by: +script plugin +
+

+ +id + is the same that was specified for +loadscript +. After the call +id + is released (can be reused for a new LoadScript). +

+ + + + Index: tags/1.1.4/doc/user/09_appendix/action_reference.html =================================================================== --- tags/1.1.4/doc/user/09_appendix/action_reference.html (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/action_reference.html (revision 818) @@ -0,0 +1,147 @@ + + + + camv-rnd user manual + + + + +

+

camv-rnd User Manual: Appendix

+

+

Action Reference

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +, + +
Action Description Syntax Plugin +
AboutPresent the about boxAbout()camv_dialogs
ActionStringExecute a pcb-rnd action parsing a string; syntac: "action(arg,arg,arg)"ActionString(action)script plugin
AddTimer (RND)Add a new timerAddTimer(action, period, [repeat], [userdata])script plugin
AnyLoad (RND)Load "anything" from path (or offer a file selectio dialog if no path specified)AnyLoad([path])
awkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
basExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
Benchmark (RND)Benchmark the GUI speed.Benchmark()
BrowseScriptsPresent a dialog box for browsing scriptsBrowseScripts()script plugin
Center (RND)Moves the pointer to the center of the window.Center()lib_hid_common plugin
ChkGridSizeReturn 1 if the currently selected grid matches the expected_size. If argument is "none" return 1 if there is no grid.ChkGridSize(expected_size)
ChkGridSize(none)
ChkGridUnitsReturn 1 if currently selected grid unit matches the expected (normally mm or mil)ChkGridUnits(expected)
ChkModeReturn 1 if the currently selected mode is the expected_modeChkMode(expected_mode)
cli_MessageBoxIntenal: CLI frontend action. Do not use directly.
cli_PromptForIntenal: CLI frontend action. Do not use directly.
CommandDisplays the command line input in the status area.Command()lib_hid_common plugin
confPerform various operations on the configuration tree.conf(set, path, value, [role], [policy]) - change a config setting to an absolute value
conf(delta, path, value, [role], [policy]) - change a config setting by a delta value (numerics-only)
conf(toggle, path, [role]) - invert boolean value of a flag; if no role given, overwrite the highest prio config
conf(reset, role) - reset the in-memory lihata of a role
conf(iseq, path, value) - returns whether the value of a conf item matches value (for menu checked's)
CreateMenuCreates a new menu, popup (only path specified) or submenu (at least path and action are specified)CreateMenu(path)
CreateMenu(path, action, tooltip, cookie, [accel])
Cursor (RND)Move the cursor.Cursor(Type,DeltaUp,DeltaRight,Units)
dadManipulate Dynamic Attribute Dialogsdad(dlgname, new) - create new dialog
dad(dlgname, label, text) - append a label widget
dad(dlgname, button, text) - append a button widget
dad(dlgname, button_closes, label, retval, ...) - standard close buttons
dad(dlgname, enum, choices) - append an enum (combo box) widget; choices is a tab separated list
dad(dlgname, bool) - append an checkbox widget (default off)
dad(dlgname, integer|real|coord, min, max) - append an input field
dad(dlgname, string) - append a single line text input field
dad(dlgname, default, val) - set the default value of a widet while creating the dialog
dad(dlgname, help, tooltip) - set the help (tooltip) text for the current widget
dad(dlgname, progress) - append a progress bar (set to 0)
dad(dlgname, preview, cb_act_prefix, minsize_x, minsize_y, [ctx]) - append a preview with a viewbox of 10*10mm, minsize in pixels
dad(dlgname, tree, cols, istree, [header]) - append tree-table widget; header is like enum values
dad(dlgname, tree_append, row, cells) - append after row (0 means last item of the root); cells is like enum values; returns a row pointer
dad(dlgname, tree_append_under, row, cells) - append at the end of the list under row (0 means last item of the root); cells is like enum values; returns a row pointer
dad(dlgname, tree_insert, row, cells) - insert before row (0 means first item of the root); cells is like enum values; returns a row pointer
dad(dlgname, begin_hbox) - begin horizontal box
dad(dlgname, begin_vbox) - begin vertical box
dad(dlgname, begin_hpane) - begin horizontal paned box
dad(dlgname, begin_vpane) - begin vertical paned box
dad(dlgname, begin_table, cols) - begin table layout box
dad(dlgname, begin_tabbed, tabnames) - begin a view with tabs; tabnames are like choices in an enum; must have as many children widgets as many names it has
dad(dlgname, end) - end the last begin
dad(dlgname, flags, flg1, flg2, ...) - change the flags of the last created widget
dad(dlgname, onchange, action) - set the action to be called on widget change
dad(dlgname, run, title) - present dlgname as a non-modal dialog
dad(dlgname, run_modal, title) - present dlgname as a modal dialog
dad(dlgname, exists) - returns wheter the named dialog exists (0 or 1)
dad(dlgname, set, widgetID, val) - changes the value of a widget in a running dialog
dad(dlgname, get, widgetID, [unit]) - return the current value of a widget
lib_hid_common plugin
dlg_confval_editPresent a dialog box for editing the value of a conf node at path.dlg_confval_edit(path, idx, role, [modal])lib_hid_common plugin
duktapeExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
DumpActionsDump all actions available.DumpActions()
dumpconfPerform various operations on the configuration tree.dumpconf(native, [verbose], [prefix]) - dump the native (binary) config tree to stdout
dumpconf(lihata, role, [prefix]) - dump in-memory lihata representation of a config tree
diag_rnd
DumpPluginDirsPrint plugins directories in a format digestable by scripts.DumpPluginDirs()
DumpPluginsPrint plugins loaded in a format digestable by scripts.DumpPlugins()
DumpVersionDump version in script readable format.DumpVersion()
estutterExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
EvalConfPerform various operations on the configuration tree.EvalConf(path) - evaluate a config path in different config sources to figure how it ended up in the native databasediag_rnd
ExecActionFileRun actions from the given file.ExecuteFile(filename)
ExportDialogOpen the export dialog.ExportDialog()lib_hid_common plugin
fawkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
fbasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
fpasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
FsdTestCentral, DAD based File Selection Dialog demoFsdTest()lib_hid_common plugin
FullScreenHide widgets to get edit area full screenFullScreen(on|off|toggle)
GetXY (RND)Get a coordinate. If x or y specified, the return value of the action is the x or y coordinate.GetXY([message, [x|y]])
GridSet the grid.grid(set, [name:]size[@offs][!unit])
grid(+|up)
grid(-|down)
grid(#N)
grid(idx, N)
grid(get)
grid(ask)
gui_FallbackColorPickIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
gui_MayOverwriteFileIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
gui_MessageBoxIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
gui_PromptForIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
HelpOn-line action helpHelp()
ircnon-modal, single-instance, single-server, single-channel irc window for online supportirc()irc plugin
javascriptExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
jsExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
LayerDialogPresent the LayerDialog box on the currently selected layerLayerDialog()camv_dialogs
ListScripts (RND)List fungw scripts, optionally filtered wiht regex pat.ListScripts([pat])script plugin
LiveScript (RND)Manage a live scriptLiveScript([new], [name])
LiveScript(load|save, name, [filame])
LiveScript(run|stop|rerun|undo, name)
script plugin
LoadFromLoad project or layer data from a file.LoadFrom(Layer|Project,filename[,format])plug_io_act
LoadScript (RND)Load a fungw scriptLoadScript(id, filename, [language])script plugin
LogManages the central, in-memory log.Log(clear, [fromID, [toID])
Log(export, [filename, [text|lihata])
LogDialogOpen the log dialog.LogDialog()lib_hid_common plugin
LogGuiLog() action GUI sectionLogGui(export, [filename, [text|lihata])
luaExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
ManagePluginsManage plugins dialog.ManagePlugins()lib_hid_common plugin
mawkExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
MenuDebugMenu debug helpers: save the merged menu in a fileMenuDebug(save, path)
MenuPatchManage menu patchesMenuPatch(load, cookie, path, desc)
MenuPatch(unload, cookie)
MenuPatch(list)
MenuPatch(InhibitInc|InhibitDec)
Message (RND)Writes a message to the log window.message([ERROR|WARNING|INFO|DEBUG,] message)
MessageBoxOpen a modal message dialog box with title and label. If icon string is not empty, display the named icon on the left. Present one or more window close buttons with different text and return value.MessageBox(icon, title, label, button_txt, button_retval, ...)
ModeChange or use the tool mode.Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)
Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)
Tool(Press|Release|Cancel|Stroke)
Tool(Save|Restore)
MoveCursorToMove the cursor to absolute coords, pan the view as needed.MoveCursorTo(x,y)
mrubyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
OnelinerExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
Pan (RND)Start or stop panning (Mode = 1 to start, 0 to stop)Pan(Mode)lib_hid_common plugin
pasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
pcb_acosscript plugin
pcb_asinscript plugin
pcb_atan2script plugin
pcb_atanscript plugin
pcb_cosscript plugin
pcb_randscript plugin
pcb_sinscript plugin
pcb_sqrtscript plugin
pcb_srandscript plugin
pcb_tanscript plugin
perlExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
PreferencesPresent the preferences dialog, optionally opening the tab requested.Preferences([tabname])lib_hid_common plugin
Print (RND)Present the print export dialog for printing the layout from the GUI.Print()
PrintActionsPrint all actions available.PrintActions()
PrintCopyrightPrint copyright notice.PrintCopyright()
PrintDialogOpen the print dialog.PrintDialog()lib_hid_common plugin
PrintFilesPrint files currently loaded.PrintFiles()
PrintPathsPrint full paths and search paths.PrintPaths()
PrintUsagePrint command line arguments of camv-rnd or a plugin loaded.PrintUsage()
PrintUsage(plugin)
PrintVersionPrint version.PrintVersion()
PromptFor (RND)Prompt for a string. Returns the string (or NULL on cancel)PromptFor([message[,default[,title]]])
pyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
pythonExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
QuitQuits the application.Quit()
RedrawRedraw the entire screenRedraw()
ReloadScript (RND)Reload a fungw scriptReloadScript(id)script plugin
RemoveMenuRecursively removes a new menu, popup (only path specified) or submenu. RemoveMenu(path, cookie)
ResetLayerReset the transformation matrix of the layer.ResetLayer(@|idx, sx[, sy])
rnd_acosscript plugin
rnd_asinscript plugin
rnd_atan2script plugin
rnd_atanscript plugin
rnd_cosscript plugin
rnd_dlg_xpm_by_nameIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
rnd_randscript plugin
rnd_sinscript plugin
rnd_sqrtscript plugin
rnd_srandscript plugin
rnd_tanscript plugin
rnd_toolbar_initFor ringdove apps: initialize the toolbar.lib_hid_common plugin
rnd_toolbar_uninitFor ringdove apps: uninitialize the toolbar.lib_hid_common plugin
rnd_zoomChange zoom level (relative, absolute, window, ...)Zoom()
Zoom([+|-|=]factor)
Zoom(x1, y1, x2, y2)
Zoom(?)
Zoom(get)
lib_hid_common plugin
RotateLayerRotates the layer addressed (@ for current) by deg degrees CCW. (The transformation is added to the current transformation matrix of the layer.)RotateLayer(@|idx, [deg])
rubyExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
ScaleLayerScales the layer addressed (@ for current) by the factor of sx and sy. If only sx is specified, it is used as sy as well. (The transformation is added to the current transformation matrix of the layer.)ScaleLayer(@|idx, [sx, [sy]])
ScriptCookie (RND)Return a cookie specific to the current script instance during script initializationScriptCookie()script plugin
ScriptPersistency (RND)Read or remove script persistency data savd on preunloadScriptPersistency(read|remove)script plugin
Scroll (RND)Scroll the viewport.Scroll(up|down|left|right, [pixels])lib_hid_common plugin
SetGridChange grid size.SetGrid(delta|*mult|/div, [unit])
SetGridOffs (RND)Change grid offset (alignment) to x_offs and y_offs. Offsets should be specified with units.SetGridOffs(x_offs, y_offs)
SetUnits (RND)Set the default measurement units.SetUnits(mm|mil)
strokeVarious gesture recognition related functionsstroke(gesture, seq)stroke plugin
sttExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
SystemRun shell commandSystem(shell_cmd)
tclExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
Tool (RND)Change or use the tool mode.Tool(Arc|Arrow|Copy|InsertPoint|Line|Lock|Move|None|PasteBuffer)
Tool(Poly|Rectangle|Remove|Rotate|Text|Thermal|Via)
Tool(Press|Release|Cancel|Stroke)
Tool(Save|Restore)
TranslateLayerTranslates (moves) the layer addressed (@ for current) by dx and dy. (The transformation is added to the current transformation matrix of the layer.)TranslateLayer(@|idx, dx, dy)
UnloadScript (RND)Unload a fungw scriptUnloadScript(id)script plugin
ZoomGUI zoomZoom()
Zoom([+|-|=]factor)
Zoom(x1, y1, x2, y2)
Zoom(?)
Zoom(get)
Zoom(auto_first)
+

RND: this action comes from librnd and is common to all ringdove applications. + + Index: tags/1.1.4/doc/user/09_appendix/action_src/layer.html =================================================================== --- tags/1.1.4/doc/user/09_appendix/action_src/layer.html (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/action_src/layer.html (revision 818) @@ -0,0 +1,18 @@ +Change a layer property or layer ordering, depending on the argument: +

+Up or down moves the layer one slot up or down in layer ordering. Top or bottom +moves the layer to the top or bottom in layer ordering. Layers are rendered +from bottom to top: layers higher on the list will render over layers lower +on the list. This matters especially if appearance/layer_alpha is 1 and +layers are solid with no translucencly. +

+Del removes the currently selected layer. +

+getidx returns the index of the currently selected layer as an integer; +getlen returns the number of layers as an integer. These are useful for +user scripting. +

+setcolor and rename changes the color or name of the currently selected layer +(new color or name supplied as a second argument). +

+all-visible and all-invisible changes visibility of all layers. \ No newline at end of file Index: tags/1.1.4/doc/user/09_appendix/dialogs.html =================================================================== --- tags/1.1.4/doc/user/09_appendix/dialogs.html (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/dialogs.html (revision 818) @@ -0,0 +1,28 @@ + + + + + camv-rnd - list of file formats + + + + + +

camv-rnd User Manual: Appendix

+

+

List of GUI dialog boxes

+ + +
ID + dialog box name + action + source + comments + +
aboutAbout sch-rndn/asrc_plugins/dialogs/dlg_about.c  +
layerLayer propertiesn/asrc_plugins/dialogs/dlg_layer.c  + +
+ + + Index: tags/1.1.4/doc/user/09_appendix/formats.html =================================================================== --- tags/1.1.4/doc/user/09_appendix/formats.html (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/formats.html (revision 818) @@ -0,0 +1,79 @@ + + + + + camv-rnd - list of file formats + + + + + +

camv-rnd User Manual: Appendix

+

+

File format support

+ + + +
plugin native state reads formats writes formats + +
io_tedax +yes +works + + tEDAx camv-rnd layer + + tEDAx camv-rnd layer +
import_excellon +no +works + + excellon drill files + +n/a +
import_gcode +no +works + + g-code CNC program + +n/a +
import_gerb +no +works + + gerber layer image + +n/a +
export_lpr +no +works + +n/a + + printer (using ps) +
export_png +no +works + +n/a + +n/a +
export_ps +no +works + +n/a + +n/a +
export_svg +no +works + +n/a + +n/a + +
+ + + Index: tags/1.1.4/doc/user/09_appendix/src/Makefile =================================================================== --- tags/1.1.4/doc/user/09_appendix/src/Makefile (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/src/Makefile (revision 818) @@ -0,0 +1,29 @@ +CAMVRND = ../../../../src/camv-rnd +CLEANFILES=../action_details.html ../action_reference.html ../formats.html ../dialogs.html + +include ../../../../Makefile.conf +include $(LIBRND_MAK) + +all: $(CLEANFILES) + +../action_details.html: ./action_compiler.sh ../action_src/*.html librnd_acts + LIBRND_LIBDIR=$(LIBRND_LIBDIR) ./action_compiler.sh ../action_src/*.html LIBRND librnd_acts/*.html > ../action_details.html + +../action_reference.html : ./dump_actions_to_html.sh $(CAMVRND) ../action_details.html librnd_acts + LIBRND_LIBDIR=$(LIBRND_LIBDIR) ./dump_actions_to_html.sh > ../action_reference.html + +librnd_acts: FORCE + svn checkout svn://svn.repo.hu/librnd/trunk/doc/action librnd_acts + +../formats.html: ../../../../src_plugins/io_*/*.pup ../../../../src_plugins/import_*/*.pup ../../../../src_plugins/export_*/*.pup + APP="camv-rnd" PLUGINS="../../../../src_plugins" $(LIBRND_LIBDIR)/gen_formats.sh > ../formats.html + + +../dialogs.html: $(CAMVRND) ./gen_dialogs.sh ./dialog_extra.awk + LIBRND_LIBDIR="$(LIBRND_LIBDIR)" ./gen_dialogs.sh > ../dialogs.html + +FORCE: + +clean: + rm $(CLEANFILES) + -rm -rf librnd_acts Index: tags/1.1.4/doc/user/09_appendix/src/action_compiler.sh =================================================================== --- tags/1.1.4/doc/user/09_appendix/src/action_compiler.sh (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/src/action_compiler.sh (revision 818) @@ -0,0 +1,10 @@ +#!/bin/sh + +APP=camv-rnd + +dump_actions() { + cd ../../../../src + ./camv-rnd --dump-actions 2>/dev/null +} + +. $LIBRND_LIBDIR/action_compiler.sh Property changes on: tags/1.1.4/doc/user/09_appendix/src/action_compiler.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/doc/user/09_appendix/src/dialog_extra.awk =================================================================== --- tags/1.1.4/doc/user/09_appendix/src/dialog_extra.awk (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/src/dialog_extra.awk (revision 818) @@ -0,0 +1,6 @@ +# extra information about dialog boxes; anything that can not be extracte +# automatically from the code. Arrays indexed by id or source. +BEGIN { + ACTION["brave"] = "brave()" +# ACTION["progress"] = "n/a"; COMMENT["progress"] = "no action API yet (but it is planned)" +} Index: tags/1.1.4/doc/user/09_appendix/src/dump_actions_to_html.sh =================================================================== --- tags/1.1.4/doc/user/09_appendix/src/dump_actions_to_html.sh (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/src/dump_actions_to_html.sh (revision 818) @@ -0,0 +1,29 @@ +#!/bin/sh + +# collates the camv-rnd action table into a html doc page + +asrc="../action_src" +lsrc="librnd_acts" + +. $LIBRND_LIBDIR/dump_actions_to_html.sh + +cd ../../../../src +camv_rnd_ver=`./camv-rnd --version` +camv_rnd_rev=`svn info ^/ | awk '/Revision:/ { + print $0 + got_rev=1 + exit + } + END { + if (!got_rev) + print "Rev unknown" + } + '` +cd ../doc/user/09_appendix/src + +print_hdr "camv-rnd" + +( + cd ../../../../src + ./camv-rnd --dump-actions 2>/dev/null +) | gen Property changes on: tags/1.1.4/doc/user/09_appendix/src/dump_actions_to_html.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/doc/user/09_appendix/src/gen_dialogs.sh =================================================================== --- tags/1.1.4/doc/user/09_appendix/src/gen_dialogs.sh (nonexistent) +++ tags/1.1.4/doc/user/09_appendix/src/gen_dialogs.sh (revision 818) @@ -0,0 +1,47 @@ +#!/bin/sh + +trunk=../../../.. + +if test -z "$LIBRND_LIBDIR" +then +# when not run from the Makefile + LIBRND_LIBDIR=`cd $trunk/doc/developer/packaging && make -f librnd_root.mk libdir` +fi + + +# exceptions +dlgtbl=' +BEGIN { + # if source filename is the index and value regex-matches either id or name + # just ignore that line + IGNORE["src_plugins/dialogs/dlg_view.c"] = "" + IGNORE["src_plugins/dialogs/act_dad.c"] = "" +} +' + +echo ' + + + + camv-rnd - list of file formats + + + + + +

camv-rnd User Manual: Appendix

+

+

List of GUI dialog boxes

+' +dlgextra="`cat dialog_extra.awk`" + +. $LIBRND_LIBDIR/devhelpers/list_dialogs.sh + +print_hdr +list_dlgs $trunk/src/*.c $trunk/src_plugins/*/*.c | gen_html + +echo ' + + + +' Property changes on: tags/1.1.4/doc/user/09_appendix/src/gen_dialogs.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/doc/user/Makefile =================================================================== --- tags/1.1.4/doc/user/Makefile (nonexistent) +++ tags/1.1.4/doc/user/Makefile (revision 818) @@ -0,0 +1,28 @@ +include ../../Makefile.conf +LIBARCHDIR=$(LIBRND_LIBARCHDIR) +SCCBOX = $(LIBRND_PREFIX)/$(LIBARCHDIR)/librnd4/scconfig/sccbox + +all: + +clean: + +distclean: + + +install_dirs_: + $(SCCBOX) mkdir -p "$(DOCDIR)/user" + +install_: + $(SCCBOX) $(HOW) *.html *.txt *.svg $(DOCDIR)/user + +install: + $(MAKE) install_dirs_ + $(MAKE) install_ HOW="install -f -d" + +linstall: + $(MAKE) install_dirs_ + $(MAKE) install_ HOW="install -f -d" + +uninstall: + $(MAKE) install_ HOW="install -f -u -d" + Index: tags/1.1.4/doc/user/index.html =================================================================== --- tags/1.1.4/doc/user/index.html (nonexistent) +++ tags/1.1.4/doc/user/index.html (revision 818) @@ -0,0 +1,15 @@ + + + + cam-rnd user manual + + + + +

camv-rnd - user manual

+ +

Table of Contents

+

+

Index: tags/1.1.4/doc/user/keys.html =================================================================== --- tags/1.1.4/doc/user/keys.html (nonexistent) +++ tags/1.1.4/doc/user/keys.html (revision 818) @@ -0,0 +1,137 @@ + + + + + + Key to action bindings + + + + + +

Key to action bindings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
key menu.lht +
+ + Zoom In 20%
Zoom(-1.2) +
- + Zoom Out 20%
Zoom(+1.2) +
: + Command Entry
Command() +
[ + Previous grid
Grid(down) +
] + Next grid
Grid(up) +
f
 n +
New
Layer(DelAll) +
f
 o +
Load...
Load(); Zoom(auto_first); +
f
 q +
Quit
Quit() +
g
 b +
Previous grid
Grid(down) +
g
 d +
Grid *2
SetGrid(*2) +
g
 f +
Next grid
Grid(up) +
g
 h +
Grid /2
SetGrid(/2) +
g
 i +
mil
SetUnits(mil) +
g
 l +
Enable local grid
conf(toggle, plugins/hid_gtk/local_grid/enable, design) +
g
 m +
mm
SetUnits(mm) +
g
 r +
Realign grid
GetXY(Click to set the grid origin); Display(ToggleGrid) +
g
 v +
Enable visible grid
conf(toggle, editor/draw_grid, design) +
l
 + +
Add from file...
Load(Layer) +
l
 - +
Remove
Layer(remove) +
l
 a +
Add from file...
Load(Layer) +
l
 b +
Move to bottom
Layer(bottom) +
l
 d +
Move down
Layer(down) +
l
 down +
Move down
Layer(down) +
l
 page_down +
Move to bottom
Layer(bottom) +
l
 page_up +
Move to top
Layer(top) +
l
 r +
Remove
Layer(remove) +
l
 t +
Move to top
Layer(top) +
l
 u +
Move up
Layer(up) +
l
 up +
Move up
Layer(up) +
n-ctrl + New
Layer(DelAll) +
p
 m
  p
    +
Manage plugins...
ManagePlugins() +
p
 m
  s
    +
Manage scripts...
BrowseScripts() +
v
 c +
Center cursor
Center() +
v
 f +
Zoom Extents
Zoom() +
w
 m +
Message Log
LogDialog() +
z
 e
   +
Zoom Extents
Zoom() +
z
 f
   +
Zoom to found
ZoomTo(found) +
z
 s
   +
Zoom to selection
ZoomTo(selected) +
z
 x
   +
Zoom Out 20%
Zoom(+1.2) +
z
 z
   +
Zoom In 20%
Zoom(-1.2) +
+ + Index: tags/1.1.4/doc/user/keytree.dot =================================================================== --- tags/1.1.4/doc/user/keytree.dot (nonexistent) +++ tags/1.1.4/doc/user/keytree.dot (revision 818) @@ -0,0 +1,61 @@ +digraph keytree { +rankdir=LR +ranksep=0.2 +"f_n" [label="{f n} \nNew" ] +"f"->"f_n" +"f_o" [label="{f o} \nLoad..." ] +"f"->"f_o" +"f_q" [label="{f q} \nQuit" ] +"f"->"f_q" +"g_b" [label="{g b} \nPrevious grid" ] +"g"->"g_b" +"g_d" [label="{g d} \nGrid *2" ] +"g"->"g_d" +"g_f" [label="{g f} \nNext grid" ] +"g"->"g_f" +"g_h" [label="{g h} \nGrid /2" ] +"g"->"g_h" +"g_i" [label="{g i} \nmil" ] +"g"->"g_i" +"g_l" [label="{g l} \nEnable local grid" ] +"g"->"g_l" +"g_m" [label="{g m} \nmm" ] +"g"->"g_m" +"g_r" [label="{g r} \nRealign grid" ] +"g"->"g_r" +"g_v" [label="{g v} \nEnable visible grid" ] +"g"->"g_v" +"l_a" [label="{l a} \nAdd from file..." ] +"l"->"l_a" +"l_b" [label="{l b} \nMove to bottom" ] +"l"->"l_b" +"l_d" [label="{l d} \nMove down" ] +"l"->"l_d" +"l_r" [label="{l r} \nRemove" ] +"l"->"l_r" +"l_t" [label="{l t} \nMove to top" ] +"l"->"l_t" +"l_u" [label="{l u} \nMove up" ] +"l"->"l_u" +"p_m_p" [label="{p m p} \nManage plugins..." ] +"p"->"p_m" +"p_m"->"p_m_p" +"p_m_s" [label="{p m s} \nManage scripts..." ] +"p_m"->"p_m_s" +"v_c" [label="{v c} \nCenter cursor" ] +"v"->"v_c" +"v_f" [label="{v f} \nZoom Extents" ] +"v"->"v_f" +"w_m" [label="{w m} \nMessage Log" ] +"w"->"w_m" +"z_e" [label="{z e} \nZoom Extents" ] +"z"->"z_e" +"z_f" [label="{z f} \nZoom to found" ] +"z"->"z_f" +"z_s" [label="{z s} \nZoom to selection" ] +"z"->"z_s" +"z_x" [label="{z x} \nZoom Out 20%" ] +"z"->"z_x" +"z_z" [label="{z z} \nZoom In 20%" ] +"z"->"z_z" +} Index: tags/1.1.4/doc/user/keytree.svg =================================================================== --- tags/1.1.4/doc/user/keytree.svg (nonexistent) +++ tags/1.1.4/doc/user/keytree.svg (revision 818) @@ -0,0 +1,431 @@ + + + + + + +keytree + + + +f_n + +{f n} +New + + + +f + +f + + + +f->f_n + + + + + +f_o + +{f o} +Load... + + + +f->f_o + + + + + +f_q + +{f q} +Quit + + + +f->f_q + + + + + +g_b + +{g b} +Previous grid + + + +g + +g + + + +g->g_b + + + + + +g_d + +{g d} +Grid *2 + + + +g->g_d + + + + + +g_f + +{g f} +Next grid + + + +g->g_f + + + + + +g_h + +{g h} +Grid /2 + + + +g->g_h + + + + + +g_i + +{g i} +mil + + + +g->g_i + + + + + +g_l + +{g l} +Enable local grid + + + +g->g_l + + + + + +g_m + +{g m} +mm + + + +g->g_m + + + + + +g_r + +{g r} +Realign grid + + + +g->g_r + + + + + +g_v + +{g v} +Enable visible grid + + + +g->g_v + + + + + +l_a + +{l a} +Add from file... + + + +l + +l + + + +l->l_a + + + + + +l_b + +{l b} +Move to bottom + + + +l->l_b + + + + + +l_d + +{l d} +Move down + + + +l->l_d + + + + + +l_r + +{l r} +Remove + + + +l->l_r + + + + + +l_t + +{l t} +Move to top + + + +l->l_t + + + + + +l_u + +{l u} +Move up + + + +l->l_u + + + + + +p_m_p + +{p m p} +Manage plugins... + + + +p + +p + + + +p_m + +p_m + + + +p->p_m + + + + + +p_m->p_m_p + + + + + +p_m_s + +{p m s} +Manage scripts... + + + +p_m->p_m_s + + + + + +v_c + +{v c} +Center cursor + + + +v + +v + + + +v->v_c + + + + + +v_f + +{v f} +Zoom Extents + + + +v->v_f + + + + + +w_m + +{w m} +Message Log + + + +w + +w + + + +w->w_m + + + + + +z_e + +{z e} +Zoom Extents + + + +z + +z + + + +z->z_e + + + + + +z_f + +{z f} +Zoom to found + + + +z->z_f + + + + + +z_s + +{z s} +Zoom to selection + + + +z->z_s + + + + + +z_x + +{z x} +Zoom Out 20% + + + +z->z_x + + + + + +z_z + +{z z} +Zoom In 20% + + + +z->z_z + + + + + Index: tags/1.1.4/doc/user/keytree.txt =================================================================== --- tags/1.1.4/doc/user/keytree.txt (nonexistent) +++ tags/1.1.4/doc/user/keytree.txt (revision 818) @@ -0,0 +1,40 @@ ++ menu.lht Zoom(-1.2) Zoom In 20% +- menu.lht Zoom(+1.2) Zoom Out 20% +: menu.lht Command() Command Entry +[ menu.lht Grid(down) Previous grid +] menu.lht Grid(up) Next grid +f;n menu.lht Layer(DelAll) New +f;o menu.lht Load(); Zoom(auto_first); Load... +f;q menu.lht Quit() Quit +g;b menu.lht Grid(down) Previous grid +g;d menu.lht SetGrid(*2) Grid *2 +g;f menu.lht Grid(up) Next grid +g;h menu.lht SetGrid(/2) Grid \0572 +g;i menu.lht SetUnits(mil) mil +g;l menu.lht conf(toggle, plugins/hid_gtk/local_grid/enable, design) Enable local grid +g;m menu.lht SetUnits(mm) mm +g;r menu.lht GetXY(Click to set the grid origin); Display(ToggleGrid) Realign grid +g;v menu.lht conf(toggle, editor/draw_grid, design) Enable visible grid +l;+ menu.lht Load(Layer) Add from file... +l;- menu.lht Layer(remove) Remove +l;a menu.lht Load(Layer) Add from file... +l;b menu.lht Layer(bottom) Move to bottom +l;d menu.lht Layer(down) Move down +l;down menu.lht Layer(down) Move down +l;page_down menu.lht Layer(bottom) Move to bottom +l;page_up menu.lht Layer(top) Move to top +l;r menu.lht Layer(remove) Remove +l;t menu.lht Layer(top) Move to top +l;u menu.lht Layer(up) Move up +l;up menu.lht Layer(up) Move up +n-ctrl menu.lht Layer(DelAll) New +p;m;p; menu.lht ManagePlugins() Manage plugins... +p;m;s; menu.lht BrowseScripts() Manage scripts... +v;c menu.lht Center() Center cursor +v;f menu.lht Zoom() Zoom Extents +w;m menu.lht LogDialog() Message Log +z;e; menu.lht Zoom() Zoom Extents +z;f; menu.lht ZoomTo(found) Zoom to found +z;s; menu.lht ZoomTo(selected) Zoom to selection +z;x; menu.lht Zoom(+1.2) Zoom Out 20% +z;z; menu.lht Zoom(-1.2) Zoom In 20% Index: tags/1.1.4/scconfig/Makefile =================================================================== --- tags/1.1.4/scconfig/Makefile (nonexistent) +++ tags/1.1.4/scconfig/Makefile (revision 818) @@ -0,0 +1,105 @@ +# --- configuration part -- + +# - generic configuration - +# where scconfig source is; this is a path to a partial or full checkout of +# svn://repo.hu/scconfig/trunk/src +LIBRND_PREFIX=/usr +SRC=src/ + +# where compiled binaries (e.g. objects) should land; should be the same as +# $(SRC) the project has its own copy of scconfig embedded +BIN=$(SRC) + +# what cflags to use to compile scconfig +USER_CFLAGS = -I. $(LIBRND_EXTRA_INCLUDE) -DLIBRND_PREFIX="$(LIBRND_PREFIX)" + +# what ldflags to use to link scconfig +USER_LDFLAGS = + +# in case hooks.c needs to link to something local +USER_OBJS = $(BIN)/util/arg_auto_set.o + +# what to build - a ./configure +all: configure revtest + +# This line imports scconfig core and default tests +include $(SRC)/default/Makefile.plugin + +# +# - PLUGINS - +# +# Comment this line if you are not interested in c99 features +#include $(SRC)/c99/Makefile.plugin + +# Comment this line if you do not need script libs to be detected +include $(SRC)/scripts/Makefile.plugin + +# Comment this line if you do not need parser libs to be detected +#include $(SRC)/parser/Makefile.plugin + +# Comment this line if you do not need to detect parser generators +include $(SRC)/parsgen/Makefile.plugin + +# Comment this line if you do not need math related libs +include $(SRC)/math/Makefile.plugin + +# Comment this line if you do not need socket/networking +include $(SRC)/socket/Makefile.plugin + +# Comment this line if you do not need user/password API detection +include $(SRC)/userpass/Makefile.plugin + +# Comment this line if you do not need gui (X11, toolkits) +#include $(SRC)/gui/Makefile.plugin + +# Comment this line if you do not need tty (nurses, slang, pty-related calls) +#include $(SRC)/tty/Makefile.plugin + +# Comment this line if you do not need software utility libs (gen*, glib) +include $(SRC)/sul/Makefile.plugin + +# Comment this line if you do not need to detect POSIX calls +#include $(SRC)/posix/Makefile.plugin + +# Uncomment this line if you need menus +#include $(SRC)/menulib/Makefile.plugin + +# Comment this line if you do not need generator (templating); conflicts with tmpasm +#include $(SRC)/generator/Makefile.plugin + +# Comment this line if you do not need tmpasm (templating); conflicts with generator +include $(SRC)/tmpasm/Makefile.plugin + +# --- you shouldn't edit the lines below --- +OBJS = $(USER_OBJS) hooks.o librnd_ver.o $(DEFAULT_NOMAIN_OBJS) $(SCRIPT_OBJS) $(PARSER_OBJS) $(GENERATOR_OBJS) $(TMPASM_OBJS) $(C99_OBJS) $(PARSGEN_OBJS) $(MATH_OBJS) $(SOCKET_OBJS) $(USERPASS_OBJS) $(GUI_OBJS) $(TTY_OBJS) $(SUL_OBJS) $(POSIX_OBJS) +CFLAGS = $(USER_CFLAGS) $(DEFAULT_CFLAGS) $(SCRIPT_CFLAGS) $(PARSER_CFLAGS) $(GENERATOR_CFLAGS) $(TMPASM_CFLAGS) $(C99_CFLAGS) $(PARSGEN_CFLAGS) $(MATH_CFLAGS) $(SOCKET_CFLAGS) $(USERPASS_CFLAGS) $(GUI_CFLAGS) $(TTY_CFLAGS) $(SUL_CFLAGS) $(POSIX_CFLAGS) $(MENULIB_CFLAGS) -I$(SRC)/default +LDFLAGS = $(USER_LDFLAGS) $(DEFAULT_LDFLAGS) $(SCRIPT_LDFLAGS) $(PARSER_LDFLAGS) $(GENERATOR_LDFLAGS) $(TMPASM_LDFLAGS) $(C99_LDFLAGS) $(PARSGEN_LDFLAGS) $(MATH_LDFLAGS) $(SOCKET_LDFLAGS) $(USERPASS_LDFLAGS) $(GUI_LDFLAGS) $(TTY_LDFLAGS) $(SUL_LDFLAGS) $(POSIX_LDFLAGS) $(MENULIB_LDFLAGS) + +configure: $(OBJS) $(DEFAULT_MAIN_OBJS) sccbox + $(CC) -o configure $(OBJS) $(DEFAULT_MAIN_OBJS) + +menuconfig: $(OBJS) $(MENULIB_OBJS) + $(CC) -o configure $(OBJS) $(MENULIB_OBJS) + +src/util/sccbox.o: src/util/sccbox.c + $(CC) -c $(CFLAGS) -o src/util/sccbox.o src/util/sccbox.c + +sccbox: src/util/sccbox.o + $(CC) $(LDFLAGS) -o sccbox src/util/sccbox.o + +LIBRNDSCC=$(LIBRND_PREFIX)/include/librnd4/librnd/scconfig +RNDHOOKS=$(LIBRNDSCC)/plugin_3state.h $(LIBRNDSCC)/hooks_common.h + +hooks.o: $(RNDHOOKS) plugins.h $(LIBRND_PREFIX)/include/librnd4/librnd/scconfig Rev.h + +librnd_ver.o: librnd_ver.c $(LIBRND_PREFIX)/include/librnd4/librnd/config.h + $(CC) -c $(CFLAGS) -o librnd_ver.o librnd_ver.c + +$(BIN)/util/arg_auto_set.o: $(SRC)/util/arg_auto_set.c $(SRC)/util/arg_auto_set.h + $(CC) -c $(CFLAGS) -o $(BIN)/util/arg_auto_set.o $(SRC)/util/arg_auto_set.c + +clean: + -rm $(OBJS) $(DEFAULT_MAIN_OBJS) configure sccbox + +distclean: clean + -rm Makefile.depgen config.cache config.log Index: tags/1.1.4/scconfig/Rev.h =================================================================== --- tags/1.1.4/scconfig/Rev.h (nonexistent) +++ tags/1.1.4/scconfig/Rev.h (revision 818) @@ -0,0 +1 @@ +static const int myrev = 800; Index: tags/1.1.4/scconfig/Rev.tab =================================================================== --- tags/1.1.4/scconfig/Rev.tab (nonexistent) +++ tags/1.1.4/scconfig/Rev.tab (revision 818) @@ -0,0 +1,8 @@ +800 configure switch over to librnd 4.1.0 +703 configure get rid of ttf support in favor of librnd vector font +697 configure ./configure shouldn't detect librnd as it depends on librnd +678 configure link against librnd-font +611 configure BINDIR in config.h +589 configure move import_gcode config into the plugin +522 configure new plugins: export +470 configure introducing revtab Index: tags/1.1.4/scconfig/hooks.c =================================================================== --- tags/1.1.4/scconfig/hooks.c (nonexistent) +++ tags/1.1.4/scconfig/hooks.c (revision 818) @@ -0,0 +1,248 @@ +#include +#include +#include "arg.h" +#include "log.h" +#include "dep.h" +#include "db.h" +#include "libs.h" +#include "tmpasm_scconfig.h" +#include "Rev.h" +#include "../util/arg_auto_set.h" + +#include + +/* we are doing /local/camv/ */ +#define LIBRND_SCCONFIG_APP_TREE "camv" + +#include +#include +#include +#include + +#define version "1.1.4" + +#define REQ_LIBRND_MAJOR 4 +#define REQ_LIBRND_MINOR 1 + + +const arg_auto_set_t disable_libs[] = { /* list of --disable-LIBs and the subtree they affect */ + {"enable-byaccic", "/local/camv/want_byaccic", arg_true, "$enable generating language files using byaccic/ureglex"}, + {"disable-byaccic", "/local/camv/want_byaccic", arg_false, "$disable generating language files byaccic/ureglex"}, + +#undef plugin_def +#undef plugin_header +#undef plugin_dep +#define plugin_def(name, desc, default_, all_) plugin3_args(name, desc) +#define plugin_header(sect) +#define plugin_dep(plg, on) +#include "plugins.h" + + {NULL, NULL, NULL, NULL} +}; + +#define TO_STR_(payload) #payload +#define TO_STR(payload) TO_STR_(payload) + + +static void help1(void) +{ + rnd_help1("camv-rnd"); + printf(" --dot_camv_rnd=path .camv-rnd config path under $HOME/\n"); +} + +/* Runs when a custom command line argument is found + returns true if no furhter argument processing should be done */ +int hook_custom_arg(const char *key, const char *value) +{ + rnd_hook_custom_arg(key, value, disable_libs); /* call arg_auto_print_options() instead */ + + if (strcmp(key, "dot_camv_rnd") == 0) { + need_value("use --dot_camv_rnd=dir"); + put("/local/camv/dot_camv_rnd", value); + return 1; + } + if (strcmp(key, "fontdir") == 0) { + fprintf(stderr, "WARNING: --fontdir is ignored -camv-rnd doesn't need it; it uses an embedded vector font\n"); + return 1; + } + + if (arg_auto_set(key, value, disable_libs) == 0) { + fprintf(stderr, "Error: unknown argument %s\n", key); + exit(1); + } + return 1; /* handled by arg_auto_set() */ + +} + + +/* Runs before anything else */ +int hook_preinit() +{ + return 0; +} + +void librnd_ver_req_min(int exact_major, int min_minor); + +/* Runs after initialization */ +int hook_postinit() +{ + db_mkdir("/local"); + db_mkdir("/local/camv"); + rnd_hook_postinit(); + + /* defaults */ + put("/local/camv/debug", sfalse); + put("/local/camv/profile", sfalse); + + put("/local/camv/librnd_prefix", TO_STR(LIBRND_PREFIX)); + put("/local/camv/dot_camv_rnd", ".camv-rnd"); + + librnd_ver_req_min(REQ_LIBRND_MAJOR, REQ_LIBRND_MINOR); + + return 0; +} + +/* Runs after all arguments are read and parsed */ +int hook_postarg() +{ + char *tmp; + const char *libad; + + put("/local/camv/librnd_template", tmp = str_concat("", TO_STR(LIBRND_PREFIX), "/", get("/local/libarchdir"), "/librnd4/scconfig/template", NULL)); + free(tmp); + + /* if librnd is installed at some custom path, we'll need to have a -I on CFLAGS and -L on LDFLAGS */ + libad = get("/local/libarchdir"); + if (((strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/include", 12) != 0) && (strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/local/include", 18) != 0)) || (strcmp(libad, "lib") != 0)) { + put("/local/camv/librnd_extra_inc", "-I" TO_STR(LIBRND_PREFIX) "/include"); + put("/local/camv/librnd_extra_ldf", tmp = str_concat("", "-L" TO_STR(LIBRND_PREFIX) "/", libad, NULL)); + free(tmp); + } + + + return rnd_hook_postarg(TO_STR(LIBRND_PREFIX), "camv-rnd"); +} + +/* Runs when things should be detected for the host system */ +int hook_detect_host() +{ + return rnd_hook_detect_host(); +} + +/* Runs when things should be detected for the target system */ +int hook_detect_target() +{ + const char *host_ansi, *host_ped, *target_ansi, *target_ped, *target_pg, *target_no_pie; + + require("cc/cc", 0, 1); + require("cc/fpic", 0, 0); + + rnd_hook_detect_cc(); + if (rnd_hook_detect_sys() != 0) + return 1; + + /* detect inline after fixing up the flags */ + require("cc/inline", 0, 0); + + require("sys/types/size/4_u_int", 0, 1); + + /* byaccic - are we able to regenerate languages? */ + if (istrue(get("/local/camv/want_byaccic"))) { + require("parsgen/byaccic/*", 0, 0); + require("parsgen/ureglex/*", 0, 0); + if (!istrue(get("parsgen/byaccic/presents")) || !istrue(get("parsgen/ureglex/presents"))) + put("/local/camv/want_parsgen_byaccic", sfalse); + else + put("/local/camv/want_parsgen_byaccic", strue); + } + else { + report("byaccic/ureglex are disabled, along with parser generation.\n"); + put("/local/camv/want_parsgen_byaccic", sfalse); + } + + return 0; +} + +static const char *IS_OK(int *generr, int val) +{ + *generr |= val; + if (val == 0) return "ok"; + return "ERROR"; +} + +/* Runs after detection hooks, should generate the output (Makefiles, etc.) */ +int hook_generate() +{ + int generr = 0; + char *tmp, *rev = "non-svn"; + + tmp = svn_info(0, "..", "Revision:"); + if (tmp != NULL) { + rev = str_concat("", "svn r", tmp, NULL); + free(tmp); + } + + logprintf(0, "scconfig generate version info: version='%s' rev='%s'\n", version, rev); + put("/local/revision", rev); + put("/local/version", version); + + put("/local/pup/sccbox", "../../scconfig/sccbox"); + + printf("Generating config.h... %s\n", IS_OK(&generr, tmpasm(NULL, "../config.h.in", "../config.h"))); + printf("Generating config.sh... %s\n", IS_OK(&generr, tmpasm(NULL, "../config.sh.in", "../config.sh"))); + printf("Generating Makefile.conf... %s\n", IS_OK(&generr, tmpasm(NULL, "../Makefile.conf.in", "../Makefile.conf"))); + printf("Generating src/Makefile... %s\n", IS_OK(&generr, tmpasm(NULL, "../src/Makefile.in", "../src/Makefile"))); + + + if (!generr) { + printf("\n\n"); + printf("=====================\n"); + printf("Configuration summary\n"); + printf("=====================\n"); + + print_sum_setting("/local/camv/debug", "Compilation for debugging"); + print_sum_setting_or("/local/camv/symbols", "Include debug symbols", istrue(get("/local/camv/debug"))); + print_sum_cfg_val("/local/prefix", "installation prefix (--prefix)"); + print_sum_cfg_val("/local/confdir", "configuration directory (--confdir)"); + print_sum_cfg_val("/local/camv/dot_camv_rnd", ".camv_rnd config dir under $HOME"); + +#undef plugin_def +#undef plugin_header +#undef plugin_dep +#define plugin_def(name, desc, default_, all_) plugin3_stat(name, desc) +#define plugin_header(sect) printf(sect); +#define plugin_dep(plg, on) +#include "plugins.h" + + if (all_plugin_check_explicit()) { + printf("\nNevertheless the configuration is complete, if you accept these differences\nyou can go on compiling.\n\n"); + generr = 1; + } + else + printf("\nConfiguration complete, ready to compile.\n\n"); + + + { + FILE *f; + f = fopen("Rev.stamp", "w"); + fprintf(f, "%d", myrev); + fclose(f); + } + + } + else + fprintf(stderr, "\nError generating some of the files\n"); + + return generr; +} + +/* Runs before everything is uninitialized */ +void hook_preuninit() +{ +} + +/* Runs at the very end, when everything is already uninitialized */ +void hook_postuninit() +{ +} + Index: tags/1.1.4/scconfig/librnd_ver.c =================================================================== --- tags/1.1.4/scconfig/librnd_ver.c (nonexistent) +++ tags/1.1.4/scconfig/librnd_ver.c (revision 818) @@ -0,0 +1,28 @@ +/* Has to be a separate compilation unit to firewall all the extra #defines + in librnd/config.h */ + +#include +#include "log.h" +#include + +unsigned long librnd_ver_get(int *major, int *minor, int *patch) +{ + if (major != NULL) *major = ((unsigned long)RND_API_VER & 0xFF0000UL) >> 16; + if (minor != NULL) *minor = ((unsigned long)RND_API_VER & 0x00FF00UL) >> 8; + if (patch != NULL) *patch = ((unsigned long)RND_API_VER & 0x0000FFUL); + return RND_API_VER; +} + +void librnd_ver_req_min(int exact_major, int min_minor) +{ + int major, minor, patch; + librnd_ver_get(&major, &minor, &patch); + if (major != exact_major) { + report("\n\nERROR: Your currently installed librnd version is %d.%d.%d but %d.x.x (>= %d.%d.0 and < %d.0.0) is required (major version mismatch)\n\n", major, minor, patch, exact_major, exact_major, min_minor, exact_major+1); + exit(1); + } + if (minor < min_minor) { + report("\n\nERROR: Your currently installed librnd version is %d.%d.%d but %d.%d.x (>= %d.%d.0 and < %d.0.0) is required (minor version mismatch)\n\n", major, minor, patch, exact_major, min_minor, exact_major, min_minor, exact_major+1); + exit(1); + } +} Index: tags/1.1.4/scconfig/plugins.h =================================================================== --- tags/1.1.4/scconfig/plugins.h (nonexistent) +++ tags/1.1.4/scconfig/plugins.h (revision 818) @@ -0,0 +1,32 @@ +/****************************************************************************** + Auto-generated by plugins/map_plugins.sh - do NOT edit, + run make map_plugins in sch-rnd/ - to change any of the data below, + edit plugins/PLUGIN/PLUGIN.pup +******************************************************************************/ + +plugin_header("\nImport plugins:\n") +plugin_def("import_excellon", "excellon drill files", sbuildin, 1) +plugin_def("import_gcode", "gcode CNC programs", sbuildin, 1) +plugin_def("import_gerb", "gerber files", sbuildin, 1) + +plugin_header("\nExport plugins:\n") +plugin_def("export_lpr", "lpr exporter (printer)", sbuildin, 1) +plugin_def("export_png", "export sheets to png", sbuildin, 1) +plugin_def("export_ps", "export sheets to ps/eps", sbuildin, 1) +plugin_def("export_svg", "export sheets to svg", sbuildin, 1) + +plugin_header("\nIO plugins (file formats):\n") +plugin_def("io_tedax", "native tEDAx layer format", sbuildin, 1) +plugin_def("std_tools", "standard drawing tools", sbuildin, 1) + +plugin_header("\nGUI:\n") +plugin_def("dialogs", "base dialogs", sbuildin, 1) +plugin_def("gui", "Graphical User Interface", sbuildin, 1) + + +plugin_dep("dialogs", "lib_hid_common") +plugin_dep("export_lpr", "export_ps") +plugin_dep("export_png", "lib_exp_pixmap") +plugin_dep("export_ps", "lib_exp_text") +plugin_dep("export_svg", "lib_exp_text") +plugin_dep("gui", "lib_hid_common") Index: tags/1.1.4/scconfig/revtest.c =================================================================== --- tags/1.1.4/scconfig/revtest.c (nonexistent) +++ tags/1.1.4/scconfig/revtest.c (revision 818) @@ -0,0 +1,85 @@ +#include +#include +#include +#include "Rev.h" + +const char *act_names[] = { + "distclean", + "configure", + "make clean", + NULL +}; + +const char *act_desc[] = { + "run 'make distclean' in trunk/", + "rerun ./configure", + "run 'make clean' in trunk/", + NULL +}; + +int act_needed[16]; + +int main(int argc, char *argv[]) +{ + char line[8192]; + int res = 0, stamp = 0, banner = 0; + FILE *f = NULL; + + if (argc > 1) { + f = fopen(argv[1], "r"); + } + if (f != NULL) { + fscanf(f, "%d", &stamp); + fclose(f); + } + + while(fgets(line, sizeof(line), stdin) != NULL) { + char *end; + int rev; + + if (*line == '#') + continue; + rev = strtol(line, &end, 10); + if (*end != '\t') + continue; + + if (rev > stamp) { + char *act, *txt; + const char **a; + int idx; + res = 1; + act = end; + while(*act == '\t') + act++; + txt = strchr(act, '\t'); + if (txt != NULL) { + *txt = '\0'; + txt++; + while(*txt == '\t') + txt++; + } + if (!banner) { + fprintf(stderr, "\nYour source tree is stale (last configured after config-milestone r%d).\nRecent new features:\n", stamp); + banner = 1; + } + fprintf(stderr, "\nr%d: %s\n", rev, txt); + for(idx = 0, a = act_names; *a != NULL; idx++, a++) + if (strstr(act, *a) != NULL) + act_needed[idx]++; + } + } + + if (res) { + const char **a; + int idx; + + fprintf(stderr, "(Stamp: %d myrev: %d)\n", stamp, myrev); + fprintf(stderr, "\nBefore running make, please do the following actions in this order:\n"); + for(idx = 0, a = act_names; *a != NULL; idx++, a++) + if (act_needed[idx]) + fprintf(stderr, " %s\n", act_desc[idx]); + fprintf(stderr, "\n"); + } + + return res; +} Index: tags/1.1.4/scconfig/template/cc.tmpasm =================================================================== --- tags/1.1.4/scconfig/template/cc.tmpasm (nonexistent) +++ tags/1.1.4/scconfig/template/cc.tmpasm (revision 818) @@ -0,0 +1,13 @@ +### set up the C compiler and flags ### + +append /local/camv/CFLAGS cc/cflags { } +append /local/camv/CFLAGS cc/fpic { } +append /local/camv/CFLAGS ?/local/camv/cflags_profile { } +append /local/camv/CFLAGS [@-I@/local/camv/root@/src_3rd@] { } +append /local/camv/LDFLAGS cc/ldflags { } +append /local/camv/LDFLAGS ?cc/rdynamic { } +append /local/camv/LDFLAGS ?/local/camv/cflags_profile { } + +put /tmpasm/OFS { } +uniq /local/camv/CFLAGS /local/camv/CFLAGS +uniq /local/camv/LDFLAGS Index: tags/1.1.4/scconfig =================================================================== --- tags/1.1.4/scconfig (nonexistent) +++ tags/1.1.4/scconfig (revision 818) Property changes on: tags/1.1.4/scconfig ___________________________________________________________________ Added: svn:externals ## -0,0 +1 ## +svn://repo.hu/scconfig/trunk/src@1849 src Index: tags/1.1.4/src/Makefile.dep =================================================================== --- tags/1.1.4/src/Makefile.dep (nonexistent) +++ tags/1.1.4/src/Makefile.dep (revision 818) @@ -0,0 +1,156 @@ +### Generated file, do not edit, run make dep ### + +../src_plugins/dialogs/dialogs.o: ../src_plugins/dialogs/dialogs.c \ + ../config.h ../src/event.h ../src_plugins/dialogs/dlg_about.h \ + ../src_plugins/dialogs/dlg_layer.h +../src_plugins/dialogs/dlg_about.o: ../src_plugins/dialogs/dlg_about.c \ + ../config.h ../src/build_run.h ../src_plugins/dialogs/dlg_about.h +../src_plugins/dialogs/dlg_layer.o: ../src_plugins/dialogs/dlg_layer.c \ + ../config.h ../src/data.h ../src/camv_typedefs.h ../src/rtree.h \ + ../src/event.h ../src_plugins/dialogs/dlg_layer.h +../src_plugins/dialogs/dlg_pref_apptab.o: \ + ../src_plugins/dialogs/dlg_pref_apptab.c ../config.h \ + ../src_plugins/dialogs/dlg_pref_general.c +../src_plugins/export_lpr/lpr.o: ../src_plugins/export_lpr/lpr.c \ + ../src_plugins/export_lpr/../export_ps/export_ps.h +../src_plugins/export_png/export_png.o: \ + ../src_plugins/export_png/export_png.c ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/draw.h ../src/export.h +../src_plugins/export_ps/eps.o: ../src_plugins/export_ps/eps.c \ + ../config.h ../src/data.h ../src/camv_typedefs.h ../src/rtree.h \ + ../src/draw.h ../src/export.h ../src_plugins/export_ps/export_ps.h +../src_plugins/export_ps/export_ps.o: \ + ../src_plugins/export_ps/export_ps.c ../config.h \ + ../src_plugins/export_ps/export_ps.h +../src_plugins/export_ps/ps.o: ../src_plugins/export_ps/ps.c ../config.h \ + ../src/data.h ../src/camv_typedefs.h ../src/rtree.h ../src/draw.h \ + ../src/export.h ../src_plugins/export_ps/export_ps.h +../src_plugins/export_svg/export_svg.o: \ + ../src_plugins/export_svg/export_svg.c ../src/export.h ../src/draw.h \ + ../src/data.h ../src/camv_typedefs.h ../src/rtree.h +../src_plugins/gui/camv_gui.o: ../src_plugins/gui/camv_gui.c ../config.h \ + ../src/event.h ../src/data.h ../src/camv_typedefs.h ../src/rtree.h \ + ../src/plug_io_act.h ../src_plugins/gui/layersel.h \ + ../src_plugins/gui/status.h ../src/draw.h +../src_plugins/gui/layersel.o: ../src_plugins/gui/layersel.c ../config.h \ + ../src/data.h ../src/camv_typedefs.h ../src/rtree.h ../src/event.h \ + ../src_plugins/gui/layersel.h +../src_plugins/gui/status.o: ../src_plugins/gui/status.c ../config.h \ + ../src/data.h ../src/camv_typedefs.h ../src/rtree.h ../src/conf_core.h \ + ../src/crosshair.h ../src_plugins/gui/status.h +../src_plugins/import_excellon/excellon.o: \ + ../src_plugins/import_excellon/excellon.c ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/plug_io.h ../src/data.h \ + ../src/obj_any.h ../src/obj_common.h ../src/obj_arc.h ../src/obj_line.h \ + ../src/obj_poly.h ../src/obj_grp.h ../src/obj_text.h +../src_plugins/import_gcode/gcode.tab.o: \ + ../src_plugins/import_gcode/gcode.tab.c \ + ../src_plugins/import_gcode/gcode_vm.h \ + ../src_plugins/import_gcode/gcode_lex.h \ + ../src_plugins/import_gcode/gcode.tab.h +../src_plugins/import_gcode/gcode_exec.o: \ + ../src_plugins/import_gcode/gcode_exec.c \ + ../src_plugins/import_gcode/gcode_vm.h \ + ../src_plugins/import_gcode/gcode_exec.h +../src_plugins/import_gcode/gcode_lex.o: \ + ../src_plugins/import_gcode/gcode_lex.c \ + ../src_plugins/import_gcode/gcode_vm.h \ + ../src_plugins/import_gcode/gcode_lex.h \ + ../src_plugins/import_gcode/gcode.tab.h +../src_plugins/import_gcode/gcode_vm.o: \ + ../src_plugins/import_gcode/gcode_vm.c \ + ../src_plugins/import_gcode/gcode_vm.h \ + ../src_plugins/import_gcode/gcode.tab.h +../src_plugins/import_gcode/import_gcode.o: \ + ../src_plugins/import_gcode/import_gcode.c ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/plug_io.h ../src/data.h \ + ../src/obj_any.h ../src/obj_common.h ../src/obj_arc.h ../src/obj_line.h \ + ../src/obj_poly.h ../src/obj_grp.h ../src/obj_text.h ../src/conf_core.h \ + ../src_plugins/import_gcode/gcode_vm.h \ + ../src_plugins/import_gcode/gcode_exec.h \ + ../src_plugins/import_gcode/import_gcode_conf.h \ + ../src_plugins/import_gcode/conf_internal.c \ + ../src_plugins/import_gcode/import_gcode_conf_fields.h +../src_plugins/import_gerb/gedraw.o: ../src_plugins/import_gerb/gedraw.c \ + ../src_plugins/import_gerb/gedraw.h ../src_plugins/import_gerb/gexpr.h \ + ../src_plugins/import_gerb/gex.tab.h \ + ../src_plugins/import_gerb/geparse.h +../src_plugins/import_gerb/geparse.o: \ + ../src_plugins/import_gerb/geparse.c \ + ../src_plugins/import_gerb/geparse.h ../src_plugins/import_gerb/gedraw.h \ + ../src_plugins/import_gerb/gexpr.h ../src_plugins/import_gerb/gex.tab.h +../src_plugins/import_gerb/gerb2camv.o: \ + ../src_plugins/import_gerb/gerb2camv.c ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/plug_io.h ../src/data.h \ + ../src/obj_any.h ../src/obj_common.h ../src/obj_arc.h ../src/obj_line.h \ + ../src/obj_poly.h ../src/obj_grp.h ../src/obj_text.h \ + ../src_plugins/import_gerb/geparse.h ../src_plugins/import_gerb/gedraw.h \ + ../src_plugins/import_gerb/gexpr.h ../src_plugins/import_gerb/gex.tab.h +../src_plugins/import_gerb/gex.tab.o: \ + ../src_plugins/import_gerb/gex.tab.c ../src_plugins/import_gerb/gexpr.h \ + ../src_plugins/import_gerb/gex.tab.h +../src_plugins/import_gerb/gexpr.o: ../src_plugins/import_gerb/gexpr.c \ + ../src_plugins/import_gerb/gexpr.h ../src_plugins/import_gerb/gex.tab.h +../src_plugins/io_tedax/io_tedax.o: ../src_plugins/io_tedax/io_tedax.c \ + ../src/camv_typedefs.h ../src/plug_io.h ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/data.h \ + ../src_plugins/io_tedax/parse.h ../src/obj_any.h ../src/obj_common.h \ + ../src/obj_arc.h ../src/obj_line.h ../src/obj_poly.h ../src/obj_grp.h \ + ../src/obj_text.h +../src_plugins/io_tedax/parse.o: ../src_plugins/io_tedax/parse.c \ + ../src_plugins/io_tedax/parse.h +../src_plugins/std_tools/std_tools.o: \ + ../src_plugins/std_tools/std_tools.c \ + ../src_plugins/std_tools/tool_mline.c \ + ../src_plugins/std_tools/tool_mline.h ../src/crosshair.h ../src/data.h \ + ../src/camv_typedefs.h ../src/rtree.h ../src/obj_any.h ../src/data.h \ + ../src/obj_common.h ../src/obj_arc.h ../src/obj_line.h ../src/obj_poly.h \ + ../src/obj_grp.h ../src/obj_text.h ../src/obj_line.h ../src/obj_text.h \ + ../src_plugins/std_tools/tool_mobj.c \ + ../src_plugins/std_tools/tool_arrow.c +build_run.o: build_run.c config.h ../config.h conf_core.h build_run.h +camv-rnd.o: camv-rnd.c config.h ../config.h gui_act.h data.h \ + camv_typedefs.h rtree.h plug_io.h plug_io_act.h conf_core.h event.h \ + crosshair.h draw.h conf_internal.c menu_internal.c buildin.c +conf_core.o: conf_core.c conf_core.h conf_core_fields.h +crosshair.o: crosshair.c event.h data.h camv_typedefs.h rtree.h \ + crosshair.h conf_core.h +data.o: data.c data.h camv_typedefs.h rtree.h obj_any.h obj_common.h \ + obj_arc.h obj_line.h obj_poly.h obj_grp.h obj_text.h conf_core.h event.h +draw.o: draw.c obj_any.h camv_typedefs.h data.h rtree.h obj_common.h \ + obj_arc.h obj_line.h obj_poly.h obj_grp.h obj_text.h conf_core.h +event.o: event.c event.h +export.o: export.c data.h camv_typedefs.h rtree.h export.h +gui_act.o: gui_act.c config.h ../config.h build_run.h data.h \ + camv_typedefs.h rtree.h +main_act.o: main_act.c config.h ../config.h conf_core.h data.h \ + camv_typedefs.h rtree.h build_run.h +obj_any.o: obj_any.c obj_any.h camv_typedefs.h data.h rtree.h \ + obj_common.h obj_arc.h obj_line.h obj_poly.h obj_grp.h obj_text.h +obj_arc.o: obj_arc.c obj_arc.h obj_common.h camv_typedefs.h rtree.h \ + obj_any.h data.h obj_line.h obj_poly.h obj_grp.h obj_text.h geo.h \ + ../src_3rd/opc89.h ../src_3rd/gengeo2d/common.h \ + ../src_3rd/gengeo2d/carc.h ../src_3rd/gengeo2d/prim.h \ + ../src_3rd/gengeo2d/vect.h ../src_3rd/gengeo2d/box.h \ + ../src_3rd/gengeo2d/sarc.h +obj_grp.o: obj_grp.c obj_grp.h obj_common.h camv_typedefs.h rtree.h \ + obj_any.h data.h obj_arc.h obj_line.h obj_poly.h obj_text.h +obj_line.o: obj_line.c obj_line.h obj_common.h camv_typedefs.h rtree.h \ + obj_any.h data.h obj_arc.h obj_poly.h obj_grp.h obj_text.h geo.h \ + ../src_3rd/opc89.h ../src_3rd/gengeo2d/common.h \ + ../src_3rd/gengeo2d/cline.h ../src_3rd/gengeo2d/prim.h \ + ../src_3rd/gengeo2d/vect.h ../src_3rd/gengeo2d/box.h +obj_poly.o: obj_poly.c obj_poly.h obj_common.h camv_typedefs.h rtree.h \ + obj_any.h data.h obj_arc.h obj_line.h obj_grp.h obj_text.h geo.h \ + ../src_3rd/opc89.h ../src_3rd/gengeo2d/common.h \ + ../src_3rd/gengeo2d/box.h ../src_3rd/gengeo2d/prim.h \ + ../src_3rd/gengeo2d/vect.h +obj_text.o: obj_text.c obj_text.h obj_common.h camv_typedefs.h rtree.h \ + obj_any.h data.h obj_arc.h obj_line.h obj_poly.h obj_grp.h conf_core.h \ + geo.h ../src_3rd/opc89.h ../src_3rd/gengeo2d/common.h \ + ../src_3rd/gengeo2d/box.h ../src_3rd/gengeo2d/prim.h \ + ../src_3rd/gengeo2d/vect.h font_internal.c +plug_io.o: plug_io.c plug_io.h data.h camv_typedefs.h rtree.h +plug_io_act.o: plug_io_act.c config.h ../config.h event.h data.h \ + camv_typedefs.h rtree.h plug_io.h plug_io_act.h +rtree.o: rtree.c rtree.h Index: tags/1.1.4/src/Makefile.in =================================================================== --- tags/1.1.4/src/Makefile.in (nonexistent) +++ tags/1.1.4/src/Makefile.in (revision 818) @@ -0,0 +1,193 @@ + +put /local/camv/root {..} +put /local/camv/CFLAGS {-I.. -I../src -Dinline= } +put /local/rnd/DEPDEPS {conf_internal.c menu_internal.c } +put /local/rnd/DEPCFLAGS {-I$(LIBRND)/include/librnd/src_3rd} + +include {template/cc.tmpasm} +include [@@/local/camv/librnd_template@/debug.tmpasm@] + +put /local/camv/OBJS [@ + camv-rnd.o + data.o + event.o + obj_any.o + obj_arc.o + obj_line.o + obj_poly.o + obj_grp.o + obj_text.o + gui_act.o + draw.o + export.o + crosshair.o + rtree.o + plug_io.o + plug_io_act.o + conf_core.o + main_act.o + build_run.o +@] + +# e.g.$(ROOT)/src_3rd/ttf2bbox/ttf_map.o +put /local/camv/LIBS_3RD [@ +@] + +uniq /local/camv/LIBS_3RD + +put /local/camv/DEPDEPS {} + + +#---- modules ----# +# extra rules for modules +put /local/rnd/CLEANFILES {} +put /local/pcb/CLEANRULES {} +put /local/pcb/EXEDEPS {} +put /local/pcb/all {} +put /local/pcb/buildin_init {} +put /local/rnd/rules/install_ {} +put /local/rnd/rules/install {} +put /local/rnd/rules/linstall {} +put /local/rnd/rules/uninstall {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/CONF {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod/YACC {} +put /local/rnd/mod/LEX {} +put /local/rnd/mod/BYACCIC {} +put /local/rnd/mod/UREGLEX {} + +put /local/camv/tmpasm/buildin {../src_plugins/Buildin.tmpasm} +put /local/camv/tmpasm/plugin {../src_plugins/Plugin.tmpasm} +put /local/camv/tmpasm/disable {../src_plugins/Disable.tmpasm} +put /local/camv/tmpasm/common_enabled {../src_plugins/Common_enabled.tmpasm} +put /local/camv/tmpasm/plugin_sphash [@@/local/camv/librnd_template@/plugin_sphash.tmpasm@] +put /local/camv/tmpasm/plugin_conf [@@/local/camv/librnd_template@/plugin_conf.tmpasm@] +put /local/camv/tmpasm/plugin_intconf [@@/local/camv/librnd_template@/plugin_intconf.tmpasm@] +put /local/camv/tmpasm/plugin_intmenu [@@/local/camv/librnd_template@/plugin_intmenu.tmpasm@] +put /local/camv/tmpasm/comp_var [@@/local/camv/librnd_template@/comp_var.tmpasm@] + +include {../src_plugins/plugins_ALL.tmpasm} + +append /local/camv/OBJS ?/local/camv/MOD_OBJS + +uniq /local/camv/OBJS + +append /local/camv/CFLAGS ?/local/camv/MOD_CFLAGS +append /local/camv/CFLAGS ?/local/camv/librnd_extra_inc +append /local/camv/LDFLAGS ?/local/camv/MOD_LDFLAGS +append /local/camv/LDFLAGS ?/local/camv/librnd_extra_ldf + +### Makefile ### + +print [@ +ROOT=@/local/camv/root@ +include $(ROOT)/Makefile.conf + +RNDLIB_LDLIBS = -lrnd-hid -lrnd-poly -lrnd-font -lrnd-core -lrnd-3rd +CC=@cc/cc@ +CFLAGS=@/local/camv/CFLAGS@ @?/local/rnd/CFLAGS@ $(CFLAGS_LIBRND) +C89FLAGS=$(CFLAGS) +CP=cp +MKDIR=mkdir -p +LDFLAGS=@/local/camv/LDFLAGS@ @?/local/rnd/LDFLAGS@ $(LDFLAGS_LIBRND) +OBJS = @/local/camv/OBJS@ +LDLIBS=$(RNDLIB_LDLIBS) $(LDFLAGS_LIBRND_FUNGW) @libs/ldl@ -lm +PLUGDIR=../src_plugins +PLUGIDIR=./plugins + +LIBMINUID_CFLAGS=@/local/camv/CFLAGS@ @?/local/rnd/CFLAGS@ +LIBMINUID_LDFLAGS=@/local/camv/LDFLAGS@ @?/local/rnd/LDFLAGS@ + +CLEAN_FILES = camv-rnd conf_core_fields.h buildin.c + +all: + $(MAKE) revcheck + $(MAKE) all_exe + +include $(ROOT)/Makefile.conf + +revcheck: + cd $(ROOT)/scconfig && ./revtest Rev.stamp < Rev.tab + +all_exe: camv-rnd @/local/pcb/all@ + +camv-rnd: $(OBJS) @/local/camv/LIBS_3RD@ + $(CC) -o camv-rnd $(OBJS) $(LDFLAGS) @/local/camv/LIBS_3RD@ $(LDLIBS) + +buildin.c: $(PLUGDIR)/.builtin.pups $(PUPLUG) + cd $(PLUGDIR) && $(PUPLUG) buildin.c "-" < $(PLUGDIR)/.builtin.pups > ../src/buildin.c + +conf_core_fields.h: conf_core.h + $(GENCONF) < conf_core.h > conf_core_fields.h + +conf_core.o: conf_core_fields.h + + +### embedded (internal) version of configs and data files ### + +conf_internal.c: conf_core.lht $(CQUOTE) + $(CQUOTE) -n camv_conf_internal < conf_core.lht > conf_internal.c + +menu_internal.c: menu.lht $(CQUOTE) + $(CQUOTE) -n camv_menu_internal < menu.lht > menu_internal.c + +### src_3rd explicit rules ### + +### misc ### +map_plugins: + cd ../src_plugins && ./map_plugins.sh + +clean: + -rm $(OBJS) camv-rnd @/local/rnd/CLEANFILES@ + +distclean: clean + -rm buildin.c conf_core_fields.h ../plugins/.builtin.pups Makefile conf_internal.c + + +install_camvrnd: + $(SCCBOX) mkdir -p "$(BINDIR)" "$(LIBDIR)/plugins" "$(CONFDIR)" + $(SCCBOX) $(HOW) "camv-rnd$(EXE)" "$(BINDIR)/camv-rnd$(EXE)" + $(SCCBOX) $(HOW) "conf_core.lht" "$(CONFDIR)/conf_core.lht" + $(SCCBOX) $(HOW) "menu.lht" "$(CONFDIR)/menu.lht" +@/local/rnd/rules/install_@ + +install: + $(MAKE) install_camvrnd HOW="install -f" + +linstall: + $(MAKE) install_camvrnd HOW="linstall -f" + +uninstall: + $(MAKE) install_camvrnd HOW="uninstall" + +@] + + +#---- rules ----# + +put /local/comp/OBJS_C89 /local/camv/OBJS +put /local/comp/C89FLAGS {$(C89FLAGS)} +include [@@/local/camv/librnd_template@/compile.tmpasm@] + +put /local/dep/OUTFN {../src/Makefile.depgen} +put /local/dep/SRCS /local/camv/OBJS +put /local/dep/CFLAGS [@@/local/camv/CFLAGS@ -I@/local/camv/librnd_prefix@/include/librnd/src_3rd@] +gsub /local/dep/SRCS {.o } {.c } +include [@@/local/camv/librnd_template@/cdep.tmpasm@] + +print [@ + +# --- Extra rules from modules --- +@?/local/camv/MOD_RULES@ +@?/local/rnd/RULES@ + +@] + + +redir {../src_plugins/.builtin.pups} +print [@# Autogenerated by ./configure - do NOT edit - contains the list of buildins +@?/local/camv/buildin_pups@ +@] Index: tags/1.1.4/src/Makefile.oc =================================================================== --- tags/1.1.4/src/Makefile.oc (nonexistent) +++ tags/1.1.4/src/Makefile.oc (revision 818) @@ -0,0 +1,125 @@ +# Generated by ./ocgen called from make dep - DO NOT EDIT THIS FILE + +camv-rnd.o: camv-rnd.c + $(CC) $(CFLAGS) -c -o camv-rnd.o camv-rnd.c + +data.o: data.c + $(CC) $(CFLAGS) -c -o data.o data.c + +event.o: event.c + $(CC) $(CFLAGS) -c -o event.o event.c + +obj_any.o: obj_any.c + $(CC) $(CFLAGS) -c -o obj_any.o obj_any.c + +obj_arc.o: obj_arc.c + $(CC) $(CFLAGS) -c -o obj_arc.o obj_arc.c + +obj_line.o: obj_line.c + $(CC) $(CFLAGS) -c -o obj_line.o obj_line.c + +obj_poly.o: obj_poly.c + $(CC) $(CFLAGS) -c -o obj_poly.o obj_poly.c + +obj_grp.o: obj_grp.c + $(CC) $(CFLAGS) -c -o obj_grp.o obj_grp.c + +obj_text.o: obj_text.c + $(CC) $(CFLAGS) -c -o obj_text.o obj_text.c + +gui_act.o: gui_act.c + $(CC) $(CFLAGS) -c -o gui_act.o gui_act.c + +draw.o: draw.c + $(CC) $(CFLAGS) -c -o draw.o draw.c + +crosshair.o: crosshair.c + $(CC) $(CFLAGS) -c -o crosshair.o crosshair.c + +rtree.o: rtree.c + $(CC) $(CFLAGS) -c -o rtree.o rtree.c + +plug_io.o: plug_io.c + $(CC) $(CFLAGS) -c -o plug_io.o plug_io.c + +plug_io_act.o: plug_io_act.c + $(CC) $(CFLAGS) -c -o plug_io_act.o plug_io_act.c + +conf_core.o: conf_core.c + $(CC) $(CFLAGS) -c -o conf_core.o conf_core.c + +main_act.o: main_act.c + $(CC) $(CFLAGS) -c -o main_act.o main_act.c + +build_run.o: build_run.c + $(CC) $(CFLAGS) -c -o build_run.o build_run.c + +../src_plugins/gui/status.o: ../src_plugins/gui/status.c + $(CC) $(CFLAGS) -c -o ../src_plugins/gui/status.o ../src_plugins/gui/status.c + +../src_plugins/gui/layersel.o: ../src_plugins/gui/layersel.c + $(CC) $(CFLAGS) -c -o ../src_plugins/gui/layersel.o ../src_plugins/gui/layersel.c + +../src_plugins/gui/camv_gui.o: ../src_plugins/gui/camv_gui.c + $(CC) $(CFLAGS) -c -o ../src_plugins/gui/camv_gui.o ../src_plugins/gui/camv_gui.c + +../src_plugins/dialogs/dialogs.o: ../src_plugins/dialogs/dialogs.c + $(CC) $(CFLAGS) -c -o ../src_plugins/dialogs/dialogs.o ../src_plugins/dialogs/dialogs.c + +../src_plugins/dialogs/dlg_about.o: ../src_plugins/dialogs/dlg_about.c + $(CC) $(CFLAGS) -c -o ../src_plugins/dialogs/dlg_about.o ../src_plugins/dialogs/dlg_about.c + +../src_plugins/dialogs/dlg_layer.o: ../src_plugins/dialogs/dlg_layer.c + $(CC) $(CFLAGS) -c -o ../src_plugins/dialogs/dlg_layer.o ../src_plugins/dialogs/dlg_layer.c + +../src_plugins/dialogs/dlg_pref_apptab.o: ../src_plugins/dialogs/dlg_pref_apptab.c + $(CC) $(CFLAGS) -c -o ../src_plugins/dialogs/dlg_pref_apptab.o ../src_plugins/dialogs/dlg_pref_apptab.c + +../src_plugins/import_gerb/gedraw.o: ../src_plugins/import_gerb/gedraw.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/gedraw.o ../src_plugins/import_gerb/gedraw.c + +../src_plugins/import_gerb/geparse.o: ../src_plugins/import_gerb/geparse.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/geparse.o ../src_plugins/import_gerb/geparse.c + +../src_plugins/import_gerb/gexpr.o: ../src_plugins/import_gerb/gexpr.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/gexpr.o ../src_plugins/import_gerb/gexpr.c + +../src_plugins/import_gerb/gex.tab.o: ../src_plugins/import_gerb/gex.tab.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/gex.tab.o ../src_plugins/import_gerb/gex.tab.c + +../src_plugins/import_gerb/gerb2camv.o: ../src_plugins/import_gerb/gerb2camv.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/gerb2camv.o ../src_plugins/import_gerb/gerb2camv.c + +../src_plugins/io_tedax/parse.o: ../src_plugins/io_tedax/parse.c + $(CC) $(CFLAGS) -c -o ../src_plugins/io_tedax/parse.o ../src_plugins/io_tedax/parse.c + +../src_plugins/io_tedax/io_tedax.o: ../src_plugins/io_tedax/io_tedax.c + $(CC) $(CFLAGS) -c -o ../src_plugins/io_tedax/io_tedax.o ../src_plugins/io_tedax/io_tedax.c + +../src_plugins/std_tools/std_tools.o: ../src_plugins/std_tools/std_tools.c + $(CC) $(CFLAGS) -c -o ../src_plugins/std_tools/std_tools.o ../src_plugins/std_tools/std_tools.c + +../src_plugins/import_excellon/excellon.o: ../src_plugins/import_excellon/excellon.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_excellon/excellon.o ../src_plugins/import_excellon/excellon.c + +../src_plugins/import_gcode/gcode.tab.o: ../src_plugins/import_gcode/gcode.tab.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gcode/gcode.tab.o ../src_plugins/import_gcode/gcode.tab.c + +../src_plugins/import_gcode/gcode_exec.o: ../src_plugins/import_gcode/gcode_exec.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gcode/gcode_exec.o ../src_plugins/import_gcode/gcode_exec.c + +../src_plugins/import_gcode/gcode_lex.o: ../src_plugins/import_gcode/gcode_lex.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gcode/gcode_lex.o ../src_plugins/import_gcode/gcode_lex.c + +../src_plugins/import_gcode/gcode_vm.o: ../src_plugins/import_gcode/gcode_vm.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gcode/gcode_vm.o ../src_plugins/import_gcode/gcode_vm.c + +../src_plugins/import_gcode/import_gcode.o: ../src_plugins/import_gcode/import_gcode.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gcode/import_gcode.o ../src_plugins/import_gcode/import_gcode.c + +../src_3rd/ttf2bbox/ttf2bbox.o: ../src_3rd/ttf2bbox/ttf2bbox.c + $(CC) $(CFLAGS) -c -o ../src_3rd/ttf2bbox/ttf2bbox.o ../src_3rd/ttf2bbox/ttf2bbox.c + +../src_plugins/import_gerb/gedump.o: ../src_plugins/import_gerb/gedump.c + $(CC) $(CFLAGS) -c -o ../src_plugins/import_gerb/gedump.o ../src_plugins/import_gerb/gedump.c + Index: tags/1.1.4/src/build_run.c =================================================================== --- tags/1.1.4/src/build_run.c (nonexistent) +++ tags/1.1.4/src/build_run.c (revision 818) @@ -0,0 +1,239 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * (this file was copied from pcb-rnd) + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * pcb-rnd Copyright (C) 2017,2018 Alain Vigne + * pcb-rnd Copyright (C) 2018,2020,2021 Tibor 'Igor2' Palinkas + * camv-rnd Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include +#include "conf_core.h" +#include "build_run.h" +#include +#include + +extern void camv_main_uninit(void); + +void camv_rnd_quit_app(void) +{ + if (rnd_gui->do_exit == NULL) { + camv_main_uninit(); + exit(0); + } + else + rnd_gui->do_exit(rnd_gui); +} + +char *camv_rnd_get_info_program(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + gds_append_str(&info, "This is camv-rnd " CAMV_VERS " (" /*CAMV_REVISION*/ ")" "\nan electronics "); + gds_append_str(&info, "related CAM file viewer\nfrom the Ringdove EDA suite\ncompiled using librnd version " RND_VER_STR "\nrunning with librnd version "); + gds_append_str(&info, rnd_ver_str); + gds_append(&info, '\n'); + } + return info.array; +} + +char *camv_rnd_get_info_copyright(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "camv-rnd copyright:\n"); + gds_append_str(&info, "Copyright (C) Tibor Palinkas 2019..2022\n"); + gds_append_str(&info, "With some code copied from fellow Ringdove application pcb-rnd\n(see http://www.repo.hu/projects/pcb-rnd)\n\n"); + } + return info.array; +} + +char *camv_rnd_get_info_websites(const char **url_out) +{ + static gds_t info; + static int first_time = 1; + static const char *URL = "http://repo.hu/projects/camv-rnd\n"; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "For more information see:\n"); + gds_append_str(&info, URL); + } + + if (url_out != NULL) + *url_out = URL; + + return info.array; +} + +char *camv_rnd_get_info_comments(void) +{ + static gds_t info; + static int first_time = 1; + char *tmp; + + if (first_time) { + first_time = 0; + gds_init(&info); + + tmp = camv_rnd_get_info_program(); + gds_append_str(&info, tmp); + tmp = camv_rnd_get_info_websites(NULL); + gds_append_str(&info, tmp); + } + return info.array; +} + + +char *camv_rnd_get_info_compile_options(void) +{ + rnd_hid_t **hids; + int i; + static gds_t info; + static int first_time = 1; + +#define TAB " " + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "----- Run Time Options -----\n"); + gds_append_str(&info, "GUI: "); + if (rnd_gui != NULL) { + gds_append_str(&info, rnd_gui->name); + gds_append_str(&info, "\n"); + } + else + gds_append_str(&info, "none\n"); + + gds_append_str(&info, "\n----- Compile Time Options -----\n"); + hids = rnd_hid_enumerate(); + gds_append_str(&info, "GUI:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->gui) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + + gds_append_str(&info, "Confdir: " CONFDIR "\n"); + gds_append_str(&info, "Libdir: " LIBDIR "\n"); + gds_append_str(&info, "librnd prefix: " LIBRND_PREFIX "\n\n"); + + gds_append_str(&info, "Exporters:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->exporter) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + + gds_append_str(&info, "Printers:\n"); + for (i = 0; hids[i]; i++) { + if (hids[i]->printer) { + gds_append_str(&info, TAB); + gds_append_str(&info, hids[i]->name); + gds_append_str(&info, " : "); + gds_append_str(&info, hids[i]->description); + gds_append_str(&info, "\n"); + } + } + } +#undef TAB + return info.array; +} + +char *camv_rnd_get_info_license(void) +{ + static gds_t info; + static int first_time = 1; + + if (first_time) { + first_time = 0; + gds_init(&info); + + gds_append_str(&info, "camv-rnd is licensed under the terms of the GNU\n"); + gds_append_str(&info, "General Public License version 2\n"); + gds_append_str(&info, "See the COPYING file for more information\n\n"); + } + return info.array; +} + +/* Catches signals which abort the program. */ +void camv_rnd_catch_signal(int Signal) +{ + const char *s; + + switch (Signal) { +#ifdef SIGHUP + case SIGHUP: + s = "SIGHUP"; + break; +#endif + case SIGINT: + s = "SIGINT"; + break; +#ifdef SIGQUIT + case SIGQUIT: + s = "SIGQUIT"; + break; +#endif + case SIGABRT: + s = "SIGABRT"; + break; + case SIGTERM: + s = "SIGTERM"; + break; + case SIGSEGV: + s = "SIGSEGV"; + break; + default: + s = "unknown"; + break; + } + rnd_message(RND_MSG_ERROR, "aborted by %s signal\n", s); + exit(1); +} Index: tags/1.1.4/src/build_run.h =================================================================== --- tags/1.1.4/src/build_run.h (nonexistent) +++ tags/1.1.4/src/build_run.h (revision 818) @@ -0,0 +1,54 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * (this file is copied from pcb-rnd, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_BUILD_RUN_H +#define PCB_BUILD_RUN_H + +void camv_rnd_quit_app(void); + +/* Returns a string that has a bunch of information about this program. */ +char *camv_rnd_get_info_program(void); + +/* Returns a string that has a bunch of information about the copyrights. */ +char *camv_rnd_get_info_copyright(void); + +/* Returns a string about how the program is licensed. */ +char *camv_rnd_get_info_license(void); + +/* Returns a string that has a bunch of information about the websites. */ +char *camv_rnd_get_info_websites(const char **url_out); + +/* Returns a string as the concatenation of camv_rnd_get_info_program() and camv_rnd_get_info_websites() */ +char *camv_rnd_get_info_comments(void); + +/* Returns a string that has a bunch of information about the options selected at compile time. */ +char *camv_rnd_get_info_compile_options(void); + +void camv_rnd_catch_signal(int Signal); + +#endif Index: tags/1.1.4/src/camv-rnd.c =================================================================== --- tags/1.1.4/src/camv-rnd.c (nonexistent) +++ tags/1.1.4/src/camv-rnd.c (revision 818) @@ -0,0 +1,234 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +/* hidlib headers */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* local (app) headers */ +#include "gui_act.h" +#include "data.h" +#include "plug_io.h" +#include "plug_io_act.h" +#include "conf_core.h" +#include "event.h" +#include "crosshair.h" +#include "draw.h" +#include "conf_internal.c" +#include "menu_internal.c" + +#define pup_buildins camv_buildins +#include "buildin.c" +#undef pup_buildins + +static const char *EXPERIMENTAL = NULL; + +static const char *menu_file_paths[] = { "./", "~/" DOT_CAMV_RND "/", NULL, NULL }; +static const char *menu_name_fmt = "menu.lht"; + +#define CONF_USER_DIR "~/" DOT_CAMV_RND + +const char *rnd_conf_userdir_path = CONF_USER_DIR; +const char *rnd_conf_user_path = CONF_USER_DIR "/conf_core.lht"; + + +extern void camv_main_act_init2(void); + +static void gui_support_plugins(int load) +{ + static int loaded = 0; + static pup_plugin_t *puphand; + + if (load && !loaded) { + static const char *plugin_name = "gui"; + int state = 0; + loaded = 1; + rnd_message(RND_MSG_DEBUG, "Loading GUI support plugin: '%s'\n", plugin_name); + puphand = pup_load(&rnd_pup, (const char **)rnd_pup_paths, plugin_name, 0, &state); + if (puphand == NULL) + rnd_message(RND_MSG_ERROR, "Error: failed to load GUI support plugin '%s'\n-> expect missing widgets and dialog boxes\n", plugin_name); + } + if (!load && loaded && (puphand != NULL)) { + pup_unload(&rnd_pup, puphand, NULL); + loaded = 0; + puphand = NULL; + } +} + +/* action table number of columns for a single action */ +const char *camv_action_args[] = { +/*short, -long, action, help, hint-on-error */ + NULL, "-show-actions", "PrintActions()", "Print all available actions (human readable) and exit", NULL, + NULL, "-dump-actions", "DumpActions()", "Print all available actions (script readable) and exit", NULL, + NULL, "-dump-plugins", "DumpPlugins()", "Print all available plugins (script readable) and exit", NULL, + NULL, "-dump-plugindirs", "DumpPluginDirs()", "Print directories plugins might be loaded from and exit", NULL, + NULL, "-show-paths", "PrintPaths()", "Print all configured paths and exit", NULL, + "V", "-version", "PrintVersion()", "Print version info and exit", NULL, + "V", "-dump-version", "DumpVersion()", "Print version info in script readable format and exit", NULL, + NULL, "-copyright", "PrintCopyright()", "Print copyright and exit", NULL, + NULL, NULL, NULL, NULL, NULL /* terminator */ +}; + +void camv_main_uninit(void) +{ + gui_support_plugins(0); + camv_design_free_fields(&camv); + camv_plug_io_act_uninit(); + rnd_hidlib_uninit(); /* plugin unload */ +} + +void camv_font_init(void); + +static void camv_main_init(void) +{ + camv.lysel = -1; + camv_font_init(); + camv_plug_io_act_init(); +} + + +int main(int argc, char *argv[]) +{ + int n; + rnd_main_args_t ga; + char *command_line_file = NULL, *exec_prefix; + + rnd_app.package = "camv-rnd"; + rnd_app.version = CAMV_VERS; + rnd_app.url = "http://repo.hu/projects/camv-rnd"; + rnd_app.multi_design = 0; + rnd_app.menu_file_paths = menu_file_paths; + rnd_app.menu_name_fmt = menu_name_fmt; + rnd_app.default_embedded_menu = camv_menu_internal; + menu_file_paths[2] = rnd_concat(CONFDIR, "/", NULL); + + + rnd_app.conf_internal = camv_conf_internal; + rnd_app.conf_sysdir_path = CONFDIR; + rnd_app.conf_sys_path = CONFDIR "/conf_core.lht"; + rnd_app.conf_userdir_path = CONF_USER_DIR; + rnd_app.conf_user_path = CONF_USER_DIR "/conf_core.lht"; + + rnd_app.crosshair_move_to = camv_hidlib_crosshair_move_to; + rnd_app.draw_attached = camv_draw_attached; + rnd_app.expose_main = camv_expose_main; + rnd_app.expose_preview = camv_expose_preview; + + rnd_app.dot_dir = CONF_USER_DIR; + rnd_app.lib_dir = LIBDIR; + + rnd_fix_locale_and_env(); + + rnd_main_args_init(&ga, argc, camv_action_args); + + exec_prefix = rnd_exec_prefix(argv[0], BINDIR, BINDIR_TO_EXECPREFIX); + rnd_hidlib_init1(conf_core_init, exec_prefix); + free(exec_prefix); + + camv_event_init_app(); + for(n = 1; n < argc; n++) + n += rnd_main_args_add(&ga, argv[n], argv[n+1]); + rnd_hidlib_init2(pup_buildins, camv_buildins); + rnd_hidlib_init3_auto(); + + camv_main_act_init2(); + gui_act_init(); + camv_main_init(); + rnd_conf_set(RND_CFR_DESIGN, "editor/view/flip_y", 0, "1", RND_POL_OVERWRITE); + + if (rnd_main_args_setup1(&ga) != 0) { + camv_main_uninit(); + rnd_main_args_uninit(&ga); + exit(1); + } + +/* Initialize actions only when the gui is already known so only the right + one is registered (there can be only one GUI). */ +TODO("action list"); +/*#include "generated_lists.h"*/ + + if (rnd_main_args_setup2(&ga, &n) != 0) { + camv_main_uninit(); + rnd_main_args_uninit(&ga); + exit(n); + } + + /* load files listed on command line, as a group, to keep their order from top to bottom */ + camv_group_load_begin(&camv); + for(n = 0; ga.hid_argc > 0; n++, ga.hid_argc--) { + if (camv_io_load(&camv, ga.hid_argv[n]) != 0) { + rnd_message(RND_MSG_ERROR, "Can not load file '%s' (specified on command line) for exporting or printing\n", ga.hid_argv[n]); + rnd_log_print_uninit_errs("Export load error"); + if (conf_core.rc.error_on_bad_cli_files) + exit(1); + } + } + camv_group_load_end(&camv); + + if (rnd_main_exported(&ga, &camv.hidlib, camv_is_empty(&camv), NULL)) { + camv_main_uninit(); + rnd_main_args_uninit(&ga); + exit(0); + } + + camv_crosshair_gui_init(); + + /* main loop */ + if (RND_HAVE_GUI_ATTR_DLG) + gui_support_plugins(1); + if (EXPERIMENTAL != NULL) { + rnd_message(RND_MSG_ERROR, "******************************** IMPORTANT ********************************\n"); + rnd_message(RND_MSG_ERROR, "This revision of camv-rnd is experimental, unstable, do NOT attempt to use\n"); + rnd_message(RND_MSG_ERROR, "it for production. The reason for this state is:\n"); + rnd_message(RND_MSG_ERROR, "%s\n", EXPERIMENTAL); + rnd_message(RND_MSG_ERROR, "******************************** IMPORTANT ********************************\n"); + } + rnd_mainloop_interactive(&ga, &camv.hidlib); + + camv_crosshair_gui_uninit(); + camv_main_uninit(); + rnd_main_args_uninit(&ga); + + { /* make sure -lrnd-poly really includes it */ + rnd_pline_t pl; + rnd_vnode_t v; + pl.head = &v; + rnd_poly_contour_init(&pl); + } + + return 0; +} Index: tags/1.1.4/src/camv_typedefs.h =================================================================== --- tags/1.1.4/src/camv_typedefs.h (nonexistent) +++ tags/1.1.4/src/camv_typedefs.h (revision 818) @@ -0,0 +1,9 @@ +#ifndef CAMV_TYPEDEFS_H +#define CAMV_TYPEDEFS_H + +typedef struct camv_design_s camv_design_t; +typedef struct camv_layer_s camv_layer_t; +typedef union camv_any_obj_u camv_any_obj_t; +typedef struct camv_grp_s camv_grp_t; + +#endif Index: tags/1.1.4/src/conf_core.c =================================================================== --- tags/1.1.4/src/conf_core.c (nonexistent) +++ tags/1.1.4/src/conf_core.c (revision 818) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "conf_core.h" + +conf_core_t conf_core; + +void conf_core_init() +{ +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_core, field,isarray,type_name,cpath,cname,desc,flags); +#include "conf_core_fields.h" +} Index: tags/1.1.4/src/conf_core.h =================================================================== --- tags/1.1.4/src/conf_core.h (nonexistent) +++ tags/1.1.4/src/conf_core.h (revision 818) @@ -0,0 +1,25 @@ +#ifndef CAMV_CONF_CORE_H +#define CAMV_CONF_CORE_H + +#include +#include + +typedef struct { + const struct { /* appearance */ + struct { /* color */ + RND_CFT_COLOR layer[16]; /* default layer colors; when a new layer is created, a color from this list is assigned initially */ + RND_CFT_COLOR attached; + } color; + RND_CFT_STRING default_font; /* OBSOLETE: used to be path to a ttf font; camv-rnd uses an embedded internal vector font now */ + RND_CFT_BOOLEAN bbox_debug; /* enable rendering bounding box of objects, for debugging */ + } appearance; + const struct rc { /* rc */ + RND_CFT_BOOLEAN error_on_bad_cli_files; + } rc; +} conf_core_t; + + +void conf_core_init(); +extern conf_core_t conf_core; + +#endif Index: tags/1.1.4/src/conf_core.lht =================================================================== --- tags/1.1.4/src/conf_core.lht (nonexistent) +++ tags/1.1.4/src/conf_core.lht (revision 818) @@ -0,0 +1,65 @@ +li:camv-rnd-conf-v1 { + ha:overwrite { + ha:editor { + draw_grid = 1 + grid_unit = mil + grid = 1 nm + li:grids = { + {0.1 mil}; {1 mil}; {5 mil}; {10 mil}; {25 mil}; {50 mil}; {100 mil}; + {0.01 mm}; {0.05 mm}; {0.1 mm}; {0.25 mm}; {0.5 mm}; {1 mm}; + } + grids_idx = 0 + ha:local_grid { + enable = 0 + radius = 16 + } + ha:global_grid { + sparse = 0 + min_dist_px = 4 + } + } + ha:rc { + menu_file = {menu.lht} + li:preferred_gui = { gtk2_gl; gtk2_gdk; gtk4_gl; lesstif; batch } + hid_fallback = 1 + error_on_bad_cli_files = 0 + } + ha:appearance { + layer_alpha = 0.75 + default_font = {/usr/share/fonts/truetype/open-sans/OpenSans-Light.ttf} + ha:loglevels { + debug_tag = {} + debug_popup = false + info_tag = {} + info_popup = false + warning_tag = {} + warning_popup = true + error_tag = {} + error_popup = true + } + ha:color { + background = {#e5e5e5} + cross = {#cdcd00} + off_limit = {#aaaaaa} + grid = {#ff0000} + attached = {#ff0000} + + li:layer = { + {#8b2323}; {#3a5fcd}; {#104e8b}; {#cd3700}; {#548b54}; + {#8b7355}; {#00868b}; {#228b22}; {#8b2323}; {#3a5fcd}; + {#104e8b}; {#cd3700}; {#548b54}; {#8b7355}; {#00868b}; + {#228b22}; + } + } + } + ha:plugins { + ha:lib_hid_common { + ha:cli_history { + file = {$(rc.path.home)/.camv-rnd/cli_history} + slots = 64 + } + } + } + } +} + Index: tags/1.1.4/src/conf_core_fields.h =================================================================== --- tags/1.1.4/src/conf_core_fields.h (nonexistent) +++ tags/1.1.4/src/conf_core_fields.h (revision 818) @@ -0,0 +1,5 @@ +conf_reg(appearance.default_font, scalar, RND_CFN_STRING, "appearance", "default_font", "OBSOLETE: used to be path to a ttf font; camv-rnd uses an embedded internal vector font now", 0) +conf_reg(appearance.bbox_debug, scalar, RND_CFN_BOOLEAN, "appearance", "bbox_debug", "enable rendering bounding box of objects, for debugging", 0) +conf_reg(appearance.color.layer, array, RND_CFN_COLOR, "appearance/color", "layer", "default layer colors; when a new layer is created, a color from this list is assigned initially", 0) +conf_reg(appearance.color.attached, scalar, RND_CFN_COLOR, "appearance/color", "attached", "", 0) +conf_reg(rc.error_on_bad_cli_files, scalar, RND_CFN_BOOLEAN, "rc", "error_on_bad_cli_files", "", 0) Index: tags/1.1.4/src/config.h =================================================================== --- tags/1.1.4/src/config.h (nonexistent) +++ tags/1.1.4/src/config.h (revision 818) @@ -0,0 +1,9 @@ +#ifndef CAMV_CONFIG_H +#define CAMV_CONFIG_H + +/* Default application symbol prefix (e.g. for RND_ACT_* macros) */ +#define RND_APP_PREFIX(x) camv_ ## x + +#include "../config.h" + +#endif Index: tags/1.1.4/src/crosshair.c =================================================================== --- tags/1.1.4/src/crosshair.c (nonexistent) +++ tags/1.1.4/src/crosshair.c (revision 818) @@ -0,0 +1,79 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "event.h" +#include +#include +#include +#include +#include + +#include "data.h" +#include "crosshair.h" +#include "conf_core.h" + +rnd_hid_gc_t camv_crosshair_gc; + +void camv_hidlib_crosshair_move_to(rnd_design_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) +{ + /* grid fit */ + abs_x = rnd_grid_fit(abs_x, hl->grid, hl->grid_ox); + abs_y = rnd_grid_fit(abs_y, hl->grid, hl->grid_ox); + camv.crosshair_x = abs_x; + camv.crosshair_y = abs_y; + + /* update the GUI */ + rnd_hid_notify_crosshair_change(hl, rnd_false); + rnd_render->set_crosshair(rnd_render, abs_x, abs_y, 0); + rnd_tool_adjust_attached(hl); + rnd_hid_notify_crosshair_change(hl, rnd_true); +} + +void camv_draw_attached(rnd_design_t *hidlib, rnd_bool inhibit_drawing_mode) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, 1, NULL); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE_XOR, 1, NULL); + + rnd_render->set_color(camv_crosshair_gc, &conf_core.appearance.color.attached); + rnd_tool_draw_attached(hidlib); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, 1, NULL); +} + +void camv_crosshair_gui_init(void) +{ + camv_crosshair_gc = rnd_hid_make_gc(); + rnd_hid_set_draw_xor(camv_crosshair_gc, 1); + camv.hidlib.grid = rnd_conf.editor.grid; +} + +void camv_crosshair_gui_uninit(void) +{ + rnd_hid_destroy_gc(camv_crosshair_gc); +} + Index: tags/1.1.4/src/crosshair.h =================================================================== --- tags/1.1.4/src/crosshair.h (nonexistent) +++ tags/1.1.4/src/crosshair.h (revision 818) @@ -0,0 +1,15 @@ +#ifndef CAMV_CROSSHAIR_H +#define CAMV_CROSSHAIR_H + +#include + +void camv_crosshair_gui_init(void); +void camv_crosshair_gui_uninit(void); + +extern rnd_hid_gc_t camv_crosshair_gc; + +void camv_hidlib_crosshair_move_to(rnd_design_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot); +void camv_draw_attached(rnd_design_t *hidlib, rnd_bool inhibit_drawing_mode); + + +#endif Index: tags/1.1.4/src/data.c =================================================================== --- tags/1.1.4/src/data.c (nonexistent) +++ tags/1.1.4/src/data.c (revision 818) @@ -0,0 +1,278 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include +#include + +#include "data.h" +#include "obj_any.h" +#include +#include "conf_core.h" +#include "event.h" + +camv_design_t camv; + +char camv_measurement_layer_name[] = "measure"; + + +void camv_layer_init(camv_layer_t *layer) +{ + static rnd_xform_mx_t ident = RND_XFORM_MX_IDENT; + + memset(layer, 0, sizeof(camv_layer_t)); + camv_rtree_init(&layer->objs); + layer->vis = 1; + memcpy(layer->mx, ident, sizeof(ident)); +} + +camv_layer_t *camv_layer_new(void) +{ + camv_layer_t *res = malloc(sizeof(camv_layer_t)); + camv_layer_init(res); + return res; +} + +void camv_group_load_begin(camv_design_t *camv) +{ + camv->grp_load = 1; + camv->grp_idx_last = -1; +} + +void camv_group_load_end(camv_design_t *camv) +{ + camv->grp_load = 0; +} + + +long camv_layer_append_to_design(camv_design_t *camv, camv_layer_t *layer) +{ + long res = -1; + + assert(layer->parent == NULL); + if (camv->grp_load) { + if (camv->grp_idx_last < 0) { + camv->grp_idx_last = camv->layers.used; + res = camv->layers.used; + vtp0_append(&camv->layers, layer); + } + else { + vtp0_insert_len(&camv->layers, camv->grp_idx_last, &layer, 1); + res = camv->grp_idx_last; + } + } + else { + res = camv->layers.used; + vtp0_append(&camv->layers, layer); + } + layer->parent = camv; + return res; +} + +long camv_sublayer_append_after(camv_design_t *camv, camv_layer_t *layer, long idx) +{ + idx++; + vtp0_insert_len(&camv->layers, idx, &layer, 1); + return idx; +} + +camv_layer_t *camv_layer_by_name(camv_design_t *camv, const char *name, int alloc) +{ + int n; + camv_layer_t *ly; + + for(n = 0; n < camv->layers.used; n++) { + ly = camv->layers.array[n]; + if ((ly->name != NULL) && (strcmp(ly->name, name) == 0)) + return camv->layers.array[n]; + } + + if (!alloc) + return NULL; + + ly = camv_layer_new(); + camv_layer_append_to_design(camv, ly); + ly->name = rnd_strdup(name); + camv_layer_invent_color(camv, ly); + rnd_event(&camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + return ly; +} + + +void camv_layer_invent_color(camv_design_t *camv, camv_layer_t *layer) +{ + static const int clrs = sizeof(conf_core.appearance.color.layer) / sizeof(conf_core.appearance.color.layer[0]); + static int next = 0; + int orig = next; + const rnd_color_t *clr; + + do { + clr = &conf_core.appearance.color.layer[next]; + next++; + if (next > clrs) + next = 0; + if (clr != NULL) + break; + } while(next != orig); + + if (clr == NULL) { + rnd_color_load_str(&layer->color, "#000000"); + rnd_message(RND_MSG_ERROR, "Internal error: camv_layer_invent_color(): no color configured\n"); + } + else + layer->color = *clr; +} + +void camv_layer_free_fields(camv_layer_t *ly) +{ + void *o; + long n; + camv_rtree_it_t it; + + free(ly->name); ly->name = NULL; + free(ly->short_name); ly->short_name = NULL; + + for(o = camv_rtree_all_first(&it, &ly->objs); o != NULL; o = camv_rtree_all_next(&it)) + camv_obj_free(o); + camv_rtree_uninit(&ly->objs); + + if (ly->parent != NULL) { + camv_design_t *camv = ly->parent; + /* optimization: go backward because the most common case is removing the last layer */ + for(n = camv->layers.used - 1; n >= 0; n--) { + if (camv->layers.array[n] == ly) { + vtp0_remove(&camv->layers, n, 1); + break; + } + } + ly->parent = NULL; + } +} + +void camv_layer_destroy(camv_layer_t *ly) +{ + camv_layer_free_fields(ly); + free(ly); +} + + +void camv_design_free_fields(camv_design_t *camv) +{ + long n; + + /* optimization: go backward to avoid memmoves */ + for(n = camv->layers.used - 1; n >= 0; n--) + camv_layer_destroy(camv->layers.array[n]); + vtp0_uninit(&camv->layers); +} + +int camv_layer_set_vis(camv_design_t *camv, rnd_cardinal_t lid_, int vis, int emit_event) +{ + long lid; + + if (lid_ >= camv->layers.used) + return -1; + + /* find the main layer */ + for(lid = lid_; (lid > 0) && (((camv_layer_t *)camv->layers.array[lid])->sub); lid--) ; + + + /* set main layer */ + ((camv_layer_t *)camv->layers.array[lid])->vis = vis; + + /* set all sublayers */ + for(lid++; (lid < camv->layers.used) && (((camv_layer_t *)camv->layers.array[lid])->sub); lid++) + ((camv_layer_t *)camv->layers.array[lid])->vis = vis; + + if (emit_event) + rnd_event(&camv->hidlib, CAMV_EVENT_LAYERVIS_CHANGED, NULL); + return 0; +} + +int camv_is_empty(camv_design_t *camv) +{ + long lid; + + for(lid = 0; lid < camv->layers.used; lid++) + if (((camv_layer_t *)camv->layers.array[lid])->objs.size != 0) + return 0; + return 1; +} + +void camv_data_bbox(camv_design_t *camv) +{ + long lid; + + camv->bbox.x1 = camv->bbox.y1 = RND_COORD_MAX; + camv->bbox.x2 = camv->bbox.y2 = -RND_COORD_MAX; + for(lid = 0; lid < camv->layers.used; lid++) { + camv_layer_t *ly = (camv_layer_t *)camv->layers.array[lid]; + if (ly->objs.size != 0) { + rnd_box_bump_point((rnd_box_t *)&camv->bbox, ly->objs.bbox.x1, ly->objs.bbox.y1); + rnd_box_bump_point((rnd_box_t *)&camv->bbox, ly->objs.bbox.x2, ly->objs.bbox.y2); + } + } + + if ((camv->bbox.x1 == RND_COORD_MAX) || (camv->bbox.y1 == RND_COORD_MAX) || (camv->bbox.x2 == -RND_COORD_MAX) || (camv->bbox.y2 == -RND_COORD_MAX)) { + /* empty layer - make it 1*1 mm so it's easier to handle */ + camv->bbox.x1 = camv->bbox.y1 = 0; + camv->bbox.x2 = camv->bbox.y2 = RND_MM_TO_COORD(1); + } +} + +void camv_layer_select(camv_design_t *camv, int idx) +{ + camv->lysel = idx; + rnd_event(&camv->hidlib, CAMV_EVENT_LAYER_SELECTED, "i", idx); +} + +void camv_data_reverse_layers(camv_design_t *camv, int inhibit_ev) +{ + vtp0_t tmp = {0}; + long n, end, i; + + /* go backward from the end, look for non-sub-layers to copy each + "layer group" at the end of tmp */ + end = camv->layers.used; + for(n = camv->layers.used-1; n >= 0; n--) { + const camv_layer_t *ly = camv->layers.array[n]; + if (!ly->sub) { + for(i = n; i < end; i++) + vtp0_append(&tmp, camv->layers.array[i]); + end = n; + } + } + + vtp0_uninit(&camv->layers); + memcpy(&camv->layers, &tmp, sizeof(vtp0_t)); + + if (!inhibit_ev) + rnd_event(&camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); +} + Index: tags/1.1.4/src/data.h =================================================================== --- tags/1.1.4/src/data.h (nonexistent) +++ tags/1.1.4/src/data.h (revision 818) @@ -0,0 +1,122 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_DATA_H +#define CAMV_DATA_H + +#include +#include "camv_typedefs.h" +#include +#include +#include +#include +#include "rtree.h" + +struct camv_design_s { + rnd_design_t hidlib; /* shall be the first */ + + /* UI states */ + rnd_coord_t crosshair_x, crosshair_y; + unsigned grp_load:1; /* if 1, we are loading a group */ + long grp_idx_last; + + /* data */ + vtp0_t layers; /* to camv_layer_t */ + int lysel; /* layer idx (lid) of the currently selected layer */ + camv_rtree_box_t bbox; + + /* for loaders */ + struct { + long ly; + } loader; +}; + +struct camv_layer_s { + camv_rtree_t objs; + rnd_color_t color; + char *name, *short_name; + camv_design_t *parent; + + + unsigned sub:1; /* if 1, layer is a sub-layer in compositing; a main layer is the first of a series of composite layers; sub layers are not visible in the layer sel */ + unsigned vis:1; /* for main layers: UI visibility */ + unsigned clearing:1; /* if 1, the layer is negative, clearing layer */ + unsigned enable_mx:1; /* if 1, apply mx (as a matrix transformation) when drawing */ + + /* cache */ + rnd_xform_mx_t mx; /* drawin/rendering mx transformation; does not affect bbox */ + double mx_sx, mx_sy, mx_rotdeg; +}; + +extern camv_design_t camv; + +void camv_layer_init(camv_layer_t *layer); +camv_layer_t *camv_layer_new(void); + +/* Create layer by unique name, return existing layer on name match, creates + non-existing layer if alloc is non-zero; appends to design automatically */ +camv_layer_t *camv_layer_by_name(camv_design_t *camv, const char *name, int alloc); + +/* Returns index of the new layer (useful for camv_sublayer_append_after()) */ +long camv_layer_append_to_design(camv_design_t *camv, camv_layer_t *layer); + +/* Appends a (typically hidden) sublayer after the last layer of the group + at idx; returns new idx for appending more sublayers */ +long camv_sublayer_append_after(camv_design_t *camv, camv_layer_t *layer, long idx); + +/* Invent a layer color for a main layer that has non set explicitly */ +void camv_layer_invent_color(camv_design_t *camv, camv_layer_t *layer); + +/* If layer is part of a design, remove it. Destroy all layer objects + and free all memory allocated by the objects or the layer. */ +void camv_layer_free_fields(camv_layer_t *ly); + +/* Free all fields of layer and layer itself as well */ +void camv_layer_destroy(camv_layer_t *layer); + +int camv_layer_set_vis(camv_design_t *camv, rnd_cardinal_t lid, int vis, int emit_event); + +void camv_design_free_fields(camv_design_t *camv); + +int camv_is_empty(camv_design_t *camv); + +void camv_data_bbox(camv_design_t *camv); + +/* Change layer selection. -1 means none selected */ +void camv_layer_select(camv_design_t *camv, int idx); + +/* reverse order of layers loaded within a group but place the whole group on + top (at the end of the vector) */ +void camv_group_load_begin(camv_design_t *camv); +void camv_group_load_end(camv_design_t *camv); + +void camv_data_reverse_layers(camv_design_t *camv, int inhibit_ev); + +#define camv_hid_redraw(camv) rnd_render->invalidate_all(rnd_render) + +extern char camv_measurement_layer_name[]; + +#endif Index: tags/1.1.4/src/depgen =================================================================== --- tags/1.1.4/src/depgen (nonexistent) +++ tags/1.1.4/src/depgen (revision 818) @@ -0,0 +1,28 @@ +#!/bin/sh + +# temporary solution until we switch over to scconfig + +RT="$1" + +echo ' +# Autogenerated - DO NOT EDIT + +include ../Makefile.conf +include $(LIBRND_PREFIX)/share/librnd3/librnd.mak +CFLAGS = -Wall -g -I. -I../src_3rd $(CFLAGS_LIBRND) -isystem '$RT'/include/librnd/src_3rd + +all: + echo "### Generated file, do not edit, run make dep ###" > Makefile.dep + echo "" >> Makefile.dep' > Makefile.depgen + +for fn in *.c +do + echo " gcc -MM $fn \$(CFLAGS) >> Makefile.dep " >> Makefile.depgen +done + +for fn in ../src_plugins/*/*.c +do + base=${fn%%.c} + fnt=$base.o + echo " gcc -MT $fnt -MM $fn \$(CFLAGS) >> Makefile.dep " >> Makefile.depgen +done Property changes on: tags/1.1.4/src/depgen ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/src/draw.c =================================================================== --- tags/1.1.4/src/draw.c (nonexistent) +++ tags/1.1.4/src/draw.c (revision 818) @@ -0,0 +1,178 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include "obj_any.h" +#include "conf_core.h" + +static rnd_coord_t MIN4(rnd_coord_t a, rnd_coord_t b, rnd_coord_t c, rnd_coord_t d) +{ + rnd_coord_t min = a; + if (b < min) min = b; + if (c < min) min = c; + if (d < min) min = d; + return min; +} + +static rnd_coord_t MAX4(rnd_coord_t a, rnd_coord_t b, rnd_coord_t c, rnd_coord_t d) +{ + rnd_coord_t max = a; + if (b > max) max = b; + if (c > max) max = c; + if (d > max) max = d; + return max; +} + +void camv_draw_layer(camv_layer_t *ly, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + camv_rtree_it_t it; + void *o; + rnd_xform_mx_t *mx = NULL; + camv_rtree_box_t vtmp, *view = (camv_rtree_box_t *)®ion->view; + + if (ly->enable_mx) { + rnd_coord_t x1, y1, x2, y2, x3, y3, x4, y4, sx, sy; + mx = &ly->mx; + ly->mx_rotdeg = rnd_xform_mx_extract_rot(*mx); + rnd_xform_mx_extract_scale(*mx, &ly->mx_sx, &ly->mx_sy); + x1 = rnd_xform_x((*mx), view->x1, view->y1); + y1 = rnd_xform_y((*mx), view->x1, view->y1); + x2 = rnd_xform_x((*mx), view->x2, view->y2); + y2 = rnd_xform_y((*mx), view->x2, view->y2); + x3 = rnd_xform_x((*mx), view->x1, view->y2); + y3 = rnd_xform_y((*mx), view->x1, view->y2); + x4 = rnd_xform_x((*mx), view->x2, view->y1); + y4 = rnd_xform_y((*mx), view->x2, view->y1); + +/* rnd_trace("orig: %mm;%mm %mm;%mm\n", view->x1, view->y1, view->x1, view->y2);*/ + sx = (view->x2 - view->x1)*2; sy = (view->y2 - view->y1)*2; + + vtmp.x1 = MIN4(x1, x2, x3, x4) - sx; vtmp.y1 = MIN4(y1, y2, y3, y4) - sy; + vtmp.x2 = MAX4(x1, x2, x3, x4) + sx; vtmp.y2 = MAX4(y1, y2, y3, y4) + sy; + + view = &vtmp; + +/* rnd_trace(" %mm;%mm %mm;%mm\n", vtmp.x1, vtmp.y1, vtmp.x2, vtmp.y2);*/ + } + + for(o = camv_rtree_first(&it, &ly->objs, view); o != NULL; o = camv_rtree_next(&it)) { + camv_any_obj_t *obj = o; + obj->proto.calls->draw(obj, gc, mx); + if (conf_core.appearance.bbox_debug) { + rnd_coord_t x1, y1, x2, y2; + + if (mx != NULL) { + x1 = rnd_xform_x((*mx), obj->proto.bbox.x1, obj->proto.bbox.y1); y1 = rnd_xform_y((*mx), obj->proto.bbox.x1, obj->proto.bbox.y1); + x2 = rnd_xform_x((*mx), obj->proto.bbox.x2, obj->proto.bbox.y2); y2 = rnd_xform_y((*mx), obj->proto.bbox.x2, obj->proto.bbox.y2); + } + else { + x1 = obj->proto.bbox.x1; y1 = obj->proto.bbox.y1; + x2 = obj->proto.bbox.x2; y2 = obj->proto.bbox.y2; + } + + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, -1); + rnd_render->draw_line(gc, x1, y1, x2, y1); + rnd_render->draw_line(gc, x2, y1, x2, y2); + rnd_render->draw_line(gc, x2, y2, x1, y2); + rnd_render->draw_line(gc, x1, y2, x1, y1); + } + } +} + +rnd_cardinal_t camv_draw_inhibit = 0; + +void camv_expose_main(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller) +{ + rnd_cardinal_t lid; + rnd_hid_gc_t gc; + int clearing = -1, direct = 1, need_flush = 0; + rnd_hid_t *save = rnd_render; + + if (camv_draw_inhibit) + return; + + if ((rnd_render != NULL) && (!rnd_render->override_render)) + rnd_render = hid; + + gc = rnd_render->make_gc(rnd_render); + + /* calculate whether the cheaper direct-draw mechanism can be done */ + for(lid = 0; lid < camv.layers.used; lid++) { + camv_layer_t *ly = camv.layers.array[lid]; + if (!ly->vis) continue; + if (ly->clearing) { + direct = 0; + break; + } + } + + /* announce start of rendering */ + rnd_render->render_burst(rnd_render, RND_HID_BURST_START, ®ion->view); + + /* the HID needs a group set, even if we don't do groups */ + if (rnd_render->set_layer_group != NULL) + rnd_render->set_layer_group(rnd_render, &camv.hidlib, 0, NULL, 0, 0, 0, 0, NULL); + + for(lid = 0; lid < camv.layers.used; lid++) { + camv_layer_t *ly = camv.layers.array[lid]; + if (!ly->vis) continue; + if (!ly->sub) { + if (need_flush) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, direct, ®ion->view); + rnd_render->end_layer(rnd_render); + } + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, direct, ®ion->view); + need_flush = 1; + + + } + + if (((int)ly->clearing != clearing) || (!ly->sub)) { + clearing = ly->clearing; + rnd_render->set_drawing_mode(rnd_render, ly->clearing ? RND_HID_COMP_NEGATIVE : RND_HID_COMP_POSITIVE, direct, ®ion->view); + } + rnd_render->set_color(gc, &ly->color); + camv_draw_layer(ly, gc, region, xform_caller); + } + + if (need_flush) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, direct, ®ion->view); + rnd_render->end_layer(rnd_render); + } + + rnd_render->render_burst(rnd_render, RND_HID_BURST_END, ®ion->view); + rnd_render->destroy_gc(gc); + + rnd_render = save; +} + +void camv_expose_preview(rnd_hid_t *hid, rnd_hid_expose_ctx_t *e) +{ + +} Index: tags/1.1.4/src/draw.h =================================================================== --- tags/1.1.4/src/draw.h (nonexistent) +++ tags/1.1.4/src/draw.h (revision 818) @@ -0,0 +1,25 @@ +#ifndef CAMV_DRAW_H +#define CAMV_DRAW_H + +typedef struct rnd_xform_s { + int dummy; +} rnd_xform_t; + +void camv_expose_main(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *region, rnd_xform_t *xform_caller); +void camv_expose_preview(rnd_hid_t *hid, rnd_hid_expose_ctx_t *e); + +/* Temporarily inhibid drawing if this is non-zero. A function that calls a + lot of other functions that would call camv_draw() a lot in turn may increase + this value before the calls, then decrease it at the end and call camv_draw(). + This makes sure the whole block is redrawn only once at the end. */ +extern rnd_cardinal_t camv_draw_inhibit; + +#define camv_draw_inhibit_inc() camv_draw_inhibit++ +#define camv_draw_inhibit_dec() \ +do { \ + if (camv_draw_inhibit > 0) \ + camv_draw_inhibit--; \ +} while(0) \ + + +#endif Index: tags/1.1.4/src/event.c =================================================================== --- tags/1.1.4/src/event.c (nonexistent) +++ tags/1.1.4/src/event.c (revision 818) @@ -0,0 +1,39 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "event.h" + +static const char *camv_evnames[] = { + "camvev_layers_changed", + "camvev_layervis_changed", + "camvev_layer_selected" +}; + +void camv_event_init_app(void) +{ + rnd_event_app_reg(CAMV_EVENT_last, camv_evnames, sizeof(camv_evnames)); +} Index: tags/1.1.4/src/event.h =================================================================== --- tags/1.1.4/src/event.h (nonexistent) +++ tags/1.1.4/src/event.h (revision 818) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_EVENT_H +#define CAMV_EVENT_H + +#include + +/* Prefix: + [d]: per-design: generated for a specific rnd_design_t + [a]: per-app: generated once, not targeted or specific for a rnd_design_t +*/ +enum { + CAMV_EVENT_LAYERS_CHANGED = RND_EVENT_app, /* [d] called after layers or layer groups change (used to be the LayersChanged action) */ + CAMV_EVENT_LAYERVIS_CHANGED, /* [d] called after the visibility of layers has changed */ + CAMV_EVENT_LAYER_SELECTED, /* [d] called when a new layer is selected; args: int layer_id */ + CAMV_EVENT_last /* not a real event */ +}; + +void camv_event_init_app(void); + +#endif Index: tags/1.1.4/src/export.c =================================================================== --- tags/1.1.4/src/export.c (nonexistent) +++ tags/1.1.4/src/export.c (revision 818) @@ -0,0 +1,72 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * (code borrowed from sch-rnd from the same author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include + +#include + +#include "data.h" +#include "export.h" + +char *camv_export_filename(rnd_design_t *hl, const char *explicit, const char *ext) +{ + camv_design_t *dsg = (camv_design_t *)hl; + gds_t tmp; + char *fn; + + if (explicit != NULL) + return rnd_strdup(explicit); + + + gds_init(&tmp); + + fn = hl->loadname; /* try to use project name first */ + if ((fn == NULL) && (dsg->layers.used > 0)) { /* if that fails, use first layer's name */ + camv_layer_t *ly = dsg->layers.array[0]; + fn = ly->name; + } + + if (fn != NULL) { + int n; + gds_append_str(&tmp, fn); + + /* truncate "extension" */ + for(n = tmp.used-1; n > 0; n--) { + if (tmp.array[n] == '.') { + tmp.used = n; + break; + } + } + } + else + gds_append_str(&tmp, "unknown"); + + gds_append_str(&tmp, ext); + + return tmp.array; /* tmp is not uninited because ownership is passed back to the caller */ +} Index: tags/1.1.4/src/export.h =================================================================== --- tags/1.1.4/src/export.h (nonexistent) +++ tags/1.1.4/src/export.h (revision 818) @@ -0,0 +1,4 @@ +#include + +char *camv_export_filename(rnd_design_t *hl, const char *explicit, const char *ext); + Index: tags/1.1.4/src/font_internal.c =================================================================== --- tags/1.1.4/src/font_internal.c (nonexistent) +++ tags/1.1.4/src/font_internal.c (revision 818) @@ -0,0 +1,818 @@ +/* This file is autogenerated by font2c.sh - DO NOT EDIT */ + +/* Internal copy of the default font; used when no font file is found */ + +static embf_line_t embf_line_32[] = { + {0,0,0,0} +}; +static embf_line_t embf_line_33[] = { /* ! */ + {0, 35, 0, 40, 8}, + {0, 0, 0, 25, 8} +}; +static embf_line_t embf_line_34[] = { /* " */ + {0, 0, 0, 10, 8}, + {10, 0, 10, 10, 8} +}; +static embf_line_t embf_line_35[] = { /* # */ + {0, 25, 20, 25, 8}, + {0, 15, 20, 15, 8}, + {15, 10, 15, 30, 8}, + {5, 10, 5, 30, 8} +}; +static embf_line_t embf_line_36[] = { /* $ */ + {15, 5, 20, 10, 8}, + {5, 5, 15, 5, 8}, + {0, 10, 5, 5, 8}, + {0, 10, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 30, 8}, + {15, 35, 20, 30, 8}, + {5, 35, 15, 35, 8}, + {0, 30, 5, 35, 8}, + {10, 0, 10, 40, 8} +}; +static embf_line_t embf_line_37[] = { /* % */ + {0, 5, 0, 10, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 10, 0, 8}, + {10, 0, 15, 5, 8}, + {15, 5, 15, 10, 8}, + {10, 15, 15, 10, 8}, + {5, 15, 10, 15, 8}, + {0, 10, 5, 15, 8}, + {0, 40, 40, 0, 8}, + {35, 40, 40, 35, 8}, + {40, 30, 40, 35, 8}, + {35, 25, 40, 30, 8}, + {30, 25, 35, 25, 8}, + {25, 30, 30, 25, 8}, + {25, 30, 25, 35, 8}, + {25, 35, 30, 40, 8}, + {30, 40, 35, 40, 8} +}; +static embf_line_t embf_line_38[] = { /* & */ + {0, 35, 5, 40, 8}, + {0, 5, 0, 15, 8}, + {0, 5, 5, 0, 8}, + {0, 25, 15, 10, 8}, + {5, 40, 10, 40, 8}, + {10, 40, 20, 30, 8}, + {0, 15, 25, 40, 8}, + {5, 0, 10, 0, 8}, + {10, 0, 15, 5, 8}, + {15, 5, 15, 10, 8}, + {0, 25, 0, 35, 8} +}; +static embf_line_t embf_line_39[] = { /* ' */ + {0, 10, 10, 0, 8} +}; +static embf_line_t embf_line_40[] = { + {0, 35, 5, 40, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8} +}; +static embf_line_t embf_line_41[] = { + {0, 0, 5, 5, 8}, + {5, 5, 5, 35, 8}, + {0, 40, 5, 35, 8} +}; +static embf_line_t embf_line_42[] = { /* * */ + {0, 10, 20, 30, 8}, + {0, 30, 20, 10, 8}, + {0, 20, 20, 20, 8}, + {10, 10, 10, 30, 8} +}; +static embf_line_t embf_line_43[] = { /* + */ + {0, 20, 20, 20, 8}, + {10, 10, 10, 30, 8} +}; +static embf_line_t embf_line_44[] = { /* , */ + {0, 50, 10, 40, 8} +}; +static embf_line_t embf_line_45[] = { /* - */ + {0, 20, 20, 20, 8} +}; +static embf_line_t embf_line_46[] = { /* . */ + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_47[] = { /* / */ + {0, 35, 30, 5, 8} +}; +static embf_line_t embf_line_48[] = { /* 0 */ + {0, 35, 5, 40, 8}, + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 30, 20, 10, 8} +}; +static embf_line_t embf_line_49[] = { /* 1 */ + {0, 8, 8, 0, 8}, + {8, 0, 8, 40, 8}, + {0, 40, 15, 40, 8} +}; +static embf_line_t embf_line_50[] = { /* 2 */ + {0, 5, 5, 0, 8}, + {5, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {0, 40, 25, 15, 8}, + {0, 40, 25, 40, 8} +}; +static embf_line_t embf_line_51[] = { /* 3 */ + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8}, + {5, 18, 15, 18, 8}, + {20, 5, 20, 13, 8}, + {20, 23, 20, 35, 8}, + {20, 23, 15, 18, 8}, + {20, 13, 15, 18, 8} +}; +static embf_line_t embf_line_52[] = { /* 4 */ + {0, 25, 20, 0, 8}, + {0, 25, 25, 25, 8}, + {20, 0, 20, 40, 8} +}; +static embf_line_t embf_line_53[] = { /* 5 */ + {0, 0, 20, 0, 8}, + {0, 0, 0, 20, 8}, + {0, 20, 5, 15, 8}, + {5, 15, 15, 15, 8}, + {15, 15, 20, 20, 8}, + {20, 20, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_54[] = { /* 6 */ + {15, 0, 20, 5, 8}, + {5, 0, 15, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {15, 18, 20, 23, 8}, + {0, 18, 15, 18, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 23, 20, 35, 8} +}; +static embf_line_t embf_line_55[] = { /* 7 */ + {5, 40, 25, 0, 8}, + {0, 0, 25, 0, 8} +}; +static embf_line_t embf_line_56[] = { /* 8 */ + {0, 35, 5, 40, 8}, + {0, 27, 0, 35, 8}, + {0, 27, 7, 20, 8}, + {7, 20, 13, 20, 8}, + {13, 20, 20, 27, 8}, + {20, 27, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 13, 7, 20, 8}, + {0, 5, 0, 13, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 13, 8}, + {13, 20, 20, 13, 8} +}; +static embf_line_t embf_line_57[] = { /* 9 */ + {5, 40, 20, 20, 8}, + {20, 5, 20, 20, 8}, + {15, 0, 20, 5, 8}, + {5, 0, 15, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 20, 20, 8} +}; +static embf_line_t embf_line_58[] = { /* : */ + {0, 15, 5, 15, 8}, + {0, 25, 5, 25, 8} +}; +static embf_line_t embf_line_59[] = { /* ; */ + {0, 40, 10, 30, 8}, + {10, 15, 10, 20, 8} +}; +static embf_line_t embf_line_60[] = { /* < */ + {0, 20, 10, 10, 8}, + {0, 20, 10, 30, 8} +}; +static embf_line_t embf_line_61[] = { /* = */ + {0, 15, 20, 15, 8}, + {0, 25, 20, 25, 8} +}; +static embf_line_t embf_line_62[] = { /* > */ + {0, 10, 10, 20, 8}, + {0, 30, 10, 20, 8} +}; +static embf_line_t embf_line_63[] = { /* ? */ + {10, 20, 10, 25, 8}, + {10, 35, 10, 40, 8}, + {0, 5, 0, 10, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 10, 8}, + {10, 20, 20, 10, 8} +}; +static embf_line_t embf_line_64[] = { /* @ */ + {0, 0, 0, 30, 8}, + {0, 30, 10, 40, 8}, + {10, 40, 40, 40, 8}, + {50, 25, 50, 0, 8}, + {50, 0, 40, -10, 8}, + {40, -10, 10, -10, 8}, + {10, -10, 0, 0, 8}, + {15, 10, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 30, 25, 8}, + {30, 25, 35, 20, 8}, + {35, 20, 40, 25, 8}, + {35, 20, 35, 5, 8}, + {35, 10, 30, 5, 8}, + {20, 5, 30, 5, 8}, + {20, 5, 15, 10, 8}, + {40, 25, 50, 25, 8} +}; +static embf_line_t embf_line_65[] = { /* A */ + {0, 10, 0, 40, 8}, + {0, 10, 7, 0, 8}, + {7, 0, 18, 0, 8}, + {18, 0, 25, 10, 8}, + {25, 10, 25, 40, 8}, + {0, 20, 25, 20, 8} +}; +static embf_line_t embf_line_66[] = { /* B */ + {0, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {25, 23, 25, 35, 8}, + {20, 18, 25, 23, 8}, + {5, 18, 20, 18, 8}, + {5, 0, 5, 40, 8}, + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 13, 8}, + {20, 18, 25, 13, 8} +}; +static embf_line_t embf_line_67[] = { /* C */ + {7, 40, 20, 40, 8}, + {0, 33, 7, 40, 8}, + {0, 7, 0, 33, 8}, + {0, 7, 7, 0, 8}, + {7, 0, 20, 0, 8} +}; +static embf_line_t embf_line_68[] = { /* D */ + {5, 0, 5, 40, 8}, + {18, 0, 25, 7, 8}, + {25, 7, 25, 33, 8}, + {18, 40, 25, 33, 8}, + {0, 40, 18, 40, 8}, + {0, 0, 18, 0, 8} +}; +static embf_line_t embf_line_69[] = { /* E */ + {0, 18, 15, 18, 8}, + {0, 40, 20, 40, 8}, + {0, 0, 0, 40, 8}, + {0, 0, 20, 0, 8} +}; +static embf_line_t embf_line_70[] = { /* F */ + {0, 0, 0, 40, 8}, + {0, 0, 20, 0, 8}, + {0, 18, 15, 18, 8} +}; +static embf_line_t embf_line_71[] = { /* G */ + {20, 0, 25, 5, 8}, + {5, 0, 20, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {25, 25, 25, 35, 8}, + {20, 20, 25, 25, 8}, + {10, 20, 20, 20, 8} +}; +static embf_line_t embf_line_72[] = { /* H */ + {0, 0, 0, 40, 8}, + {25, 0, 25, 40, 8}, + {0, 20, 25, 20, 8} +}; +static embf_line_t embf_line_73[] = { /* I */ + {0, 0, 10, 0, 8}, + {5, 0, 5, 40, 8}, + {0, 40, 10, 40, 8} +}; +static embf_line_t embf_line_74[] = { /* J */ + {7, 0, 15, 0, 8}, + {15, 0, 15, 35, 8}, + {10, 40, 15, 35, 8}, + {5, 40, 10, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 35, 0, 30, 8} +}; +static embf_line_t embf_line_75[] = { /* K */ + {0, 0, 0, 40, 8}, + {0, 20, 20, 0, 8}, + {0, 20, 20, 40, 8} +}; +static embf_line_t embf_line_76[] = { /* L */ + {0, 0, 0, 40, 8}, + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_77[] = { /* M */ + {0, 0, 0, 40, 8}, + {0, 0, 15, 20, 8}, + {15, 20, 30, 0, 8}, + {30, 0, 30, 40, 8} +}; +static embf_line_t embf_line_78[] = { /* N */ + {0, 0, 0, 40, 8}, + {0, 0, 25, 40, 8}, + {25, 0, 25, 40, 8} +}; +static embf_line_t embf_line_79[] = { /* O */ + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_80[] = { /* P */ + {5, 0, 5, 40, 8}, + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {20, 20, 25, 15, 8}, + {5, 20, 20, 20, 8} +}; +static embf_line_t embf_line_81[] = { /* Q */ + {0, 5, 0, 35, 8}, + {0, 5, 5, 0, 8}, + {5, 0, 15, 0, 8}, + {15, 0, 20, 5, 8}, + {20, 5, 20, 30, 8}, + {10, 40, 20, 30, 8}, + {5, 40, 10, 40, 8}, + {0, 35, 5, 40, 8}, + {10, 25, 20, 40, 8} +}; +static embf_line_t embf_line_82[] = { /* R */ + {0, 0, 20, 0, 8}, + {20, 0, 25, 5, 8}, + {25, 5, 25, 15, 8}, + {20, 20, 25, 15, 8}, + {5, 20, 20, 20, 8}, + {5, 0, 5, 40, 8}, + {13, 20, 25, 40, 8} +}; +static embf_line_t embf_line_83[] = { /* S */ + {20, 0, 25, 5, 8}, + {5, 0, 20, 0, 8}, + {0, 5, 5, 0, 8}, + {0, 5, 0, 15, 8}, + {0, 15, 5, 20, 8}, + {5, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {25, 25, 25, 35, 8}, + {20, 40, 25, 35, 8}, + {5, 40, 20, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_84[] = { /* T */ + {0, 0, 20, 0, 8}, + {10, 0, 10, 40, 8} +}; +static embf_line_t embf_line_85[] = { /* U */ + {0, 0, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 0, 20, 35, 8} +}; +static embf_line_t embf_line_86[] = { /* V */ + {0, 0, 10, 40, 8}, + {10, 40, 20, 0, 8} +}; +static embf_line_t embf_line_87[] = { /* W */ + {0, 0, 0, 20, 8}, + {0, 20, 5, 40, 8}, + {5, 40, 15, 20, 8}, + {15, 20, 25, 40, 8}, + {25, 40, 30, 20, 8}, + {30, 20, 30, 0, 8} +}; +static embf_line_t embf_line_88[] = { /* X */ + {0, 40, 25, 0, 8}, + {0, 0, 25, 40, 8} +}; +static embf_line_t embf_line_89[] = { /* Y */ + {0, 0, 10, 20, 8}, + {10, 20, 20, 0, 8}, + {10, 20, 10, 40, 8} +}; +static embf_line_t embf_line_90[] = { /* Z */ + {0, 0, 25, 0, 8}, + {0, 40, 25, 0, 8}, + {0, 40, 25, 40, 8} +}; +static embf_line_t embf_line_91[] = { /* [ */ + {0, 0, 5, 0, 8}, + {0, 0, 0, 40, 8}, + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_92[] = { /* \ */ + {0, 5, 30, 35, 8} +}; +static embf_line_t embf_line_93[] = { /* ] */ + {0, 0, 5, 0, 8}, + {5, 0, 5, 40, 8}, + {0, 40, 5, 40, 8} +}; +static embf_line_t embf_line_94[] = { /* ^ */ + {0, 5, 5, 0, 8}, + {5, 0, 10, 5, 8} +}; +static embf_line_t embf_line_95[] = { /* _ */ + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_97[] = { /* a */ + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {20, 20, 20, 35, 8}, + {20, 35, 25, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_98[] = { /* b */ + {0, 0, 0, 40, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 25, 20, 35, 8}, + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8} +}; +static embf_line_t embf_line_99[] = { /* c */ + {5, 20, 20, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 20, 40, 8} +}; +static embf_line_t embf_line_100[] = { /* d */ + {20, 0, 20, 40, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8} +}; +static embf_line_t embf_line_101[] = { /* e */ + {5, 40, 20, 40, 8}, + {0, 35, 5, 40, 8}, + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {0, 30, 20, 30, 8}, + {20, 30, 20, 25, 8} +}; +static embf_line_t embf_line_102[] = { /* f */ + {5, 5, 5, 40, 8}, + {5, 5, 10, 0, 8}, + {10, 0, 15, 0, 8}, + {0, 20, 10, 20, 8} +}; +static embf_line_t embf_line_103[] = { /* g */ + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {0, 50, 5, 55, 8}, + {5, 55, 15, 55, 8}, + {15, 55, 20, 50, 8}, + {20, 20, 20, 50, 8} +}; +static embf_line_t embf_line_104[] = { /* h */ + {0, 0, 0, 40, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8} +}; +static embf_line_t embf_line_105[] = { /* i */ + {0, 10, 0, 11, 10}, + {0, 25, 0, 40, 8} +}; +static embf_line_t embf_line_106[] = { /* j */ + {5, 10, 5, 11, 10}, + {5, 25, 5, 50, 8}, + {0, 55, 5, 50, 8} +}; +static embf_line_t embf_line_107[] = { /* k */ + {0, 0, 0, 40, 8}, + {0, 25, 15, 40, 8}, + {0, 25, 10, 15, 8} +}; +static embf_line_t embf_line_108[] = { /* l */ + {0, 0, 0, 35, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_109[] = { /* m */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8}, + {20, 25, 25, 20, 8}, + {25, 20, 30, 20, 8}, + {30, 20, 35, 25, 8}, + {35, 25, 35, 40, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_110[] = { /* n */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 40, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_111[] = { /* o */ + {0, 25, 0, 35, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 15, 20, 8}, + {15, 20, 20, 25, 8}, + {20, 25, 20, 35, 8}, + {15, 40, 20, 35, 8}, + {5, 40, 15, 40, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_112[] = { /* p */ + {5, 25, 5, 55, 8}, + {0, 20, 5, 25, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {25, 25, 25, 35, 8}, + {20, 40, 25, 35, 8}, + {10, 40, 20, 40, 8}, + {5, 35, 10, 40, 8} +}; +static embf_line_t embf_line_113[] = { /* q */ + {20, 25, 20, 55, 8}, + {15, 20, 20, 25, 8}, + {5, 20, 15, 20, 8}, + {0, 25, 5, 20, 8}, + {0, 25, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_114[] = { /* r */ + {5, 25, 5, 40, 8}, + {5, 25, 10, 20, 8}, + {10, 20, 20, 20, 8}, + {0, 20, 5, 25, 8} +}; +static embf_line_t embf_line_115[] = { /* s */ + {5, 40, 20, 40, 8}, + {20, 40, 25, 35, 8}, + {20, 30, 25, 35, 8}, + {5, 30, 20, 30, 8}, + {0, 25, 5, 30, 8}, + {0, 25, 5, 20, 8}, + {5, 20, 20, 20, 8}, + {20, 20, 25, 25, 8}, + {0, 35, 5, 40, 8} +}; +static embf_line_t embf_line_116[] = { /* t */ + {5, 0, 5, 35, 8}, + {5, 35, 10, 40, 8}, + {0, 15, 10, 15, 8} +}; +static embf_line_t embf_line_117[] = { /* u */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8}, + {20, 20, 20, 35, 8} +}; +static embf_line_t embf_line_118[] = { /* v */ + {0, 20, 10, 40, 8}, + {20, 20, 10, 40, 8} +}; +static embf_line_t embf_line_119[] = { /* w */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {5, 40, 10, 40, 8}, + {10, 40, 15, 35, 8}, + {15, 20, 15, 35, 8}, + {15, 35, 20, 40, 8}, + {20, 40, 25, 40, 8}, + {25, 40, 30, 35, 8}, + {30, 20, 30, 35, 8} +}; +static embf_line_t embf_line_120[] = { /* x */ + {0, 20, 20, 40, 8}, + {0, 40, 20, 20, 8} +}; +static embf_line_t embf_line_121[] = { /* y */ + {0, 20, 0, 35, 8}, + {0, 35, 5, 40, 8}, + {20, 20, 20, 50, 8}, + {15, 55, 20, 50, 8}, + {5, 55, 15, 55, 8}, + {0, 50, 5, 55, 8}, + {5, 40, 15, 40, 8}, + {15, 40, 20, 35, 8} +}; +static embf_line_t embf_line_122[] = { /* z */ + {0, 20, 20, 20, 8}, + {0, 40, 20, 20, 8}, + {0, 40, 20, 40, 8} +}; +static embf_line_t embf_line_123[] = { + {5, 5, 10, 0, 8}, + {5, 5, 5, 15, 8}, + {0, 20, 5, 15, 8}, + {0, 20, 5, 25, 8}, + {5, 25, 5, 35, 8}, + {5, 35, 10, 40, 8} +}; +static embf_line_t embf_line_124[] = { /* | */ + {0, 0, 0, 40, 8} +}; +static embf_line_t embf_line_125[] = { + {0, 0, 5, 5, 8}, + {5, 5, 5, 15, 8}, + {5, 15, 10, 20, 8}, + {5, 25, 10, 20, 8}, + {5, 25, 5, 35, 8}, + {0, 40, 5, 35, 8} +}; +static embf_line_t embf_line_126[] = { /* ~ */ + {0, 25, 5, 20, 8}, + {5, 20, 10, 20, 8}, + {10, 20, 15, 25, 8}, + {15, 25, 20, 25, 8}, + {20, 25, 25, 20, 8} +}; +/***************************************************************/ +static int embf_minx = 0; +static int embf_miny = -10; +static int embf_maxx = 50; +static int embf_maxy = 55; +static embf_font_t embf_font[] = { + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {0, NULL, 0}, + {18, embf_line_32, 0}, + {12, embf_line_33, 2}, + {12, embf_line_34, 2}, + {12, embf_line_35, 4}, + {12, embf_line_36, 12}, + {12, embf_line_37, 17}, + {12, embf_line_38, 11}, + {12, embf_line_39, 1}, + {12, embf_line_40, 3}, + {12, embf_line_41, 3}, + {12, embf_line_42, 4}, + {12, embf_line_43, 2}, + {12, embf_line_44, 1}, + {12, embf_line_45, 1}, + {12, embf_line_46, 1}, + {12, embf_line_47, 1}, + {12, embf_line_48, 9}, + {12, embf_line_49, 3}, + {12, embf_line_50, 6}, + {12, embf_line_51, 11}, + {12, embf_line_52, 3}, + {12, embf_line_53, 9}, + {12, embf_line_54, 10}, + {12, embf_line_55, 2}, + {12, embf_line_56, 15}, + {12, embf_line_57, 8}, + {12, embf_line_58, 2}, + {12, embf_line_59, 2}, + {12, embf_line_60, 2}, + {12, embf_line_61, 2}, + {12, embf_line_62, 2}, + {12, embf_line_63, 8}, + {12, embf_line_64, 17}, + {12, embf_line_65, 6}, + {12, embf_line_66, 10}, + {12, embf_line_67, 5}, + {12, embf_line_68, 6}, + {12, embf_line_69, 4}, + {12, embf_line_70, 3}, + {12, embf_line_71, 10}, + {12, embf_line_72, 3}, + {12, embf_line_73, 3}, + {12, embf_line_74, 6}, + {12, embf_line_75, 3}, + {12, embf_line_76, 2}, + {12, embf_line_77, 4}, + {12, embf_line_78, 3}, + {12, embf_line_79, 8}, + {12, embf_line_80, 6}, + {12, embf_line_81, 9}, + {12, embf_line_82, 7}, + {12, embf_line_83, 11}, + {12, embf_line_84, 2}, + {12, embf_line_85, 5}, + {12, embf_line_86, 2}, + {12, embf_line_87, 6}, + {12, embf_line_88, 2}, + {12, embf_line_89, 3}, + {12, embf_line_90, 3}, + {12, embf_line_91, 3}, + {12, embf_line_92, 1}, + {12, embf_line_93, 3}, + {12, embf_line_94, 2}, + {12, embf_line_95, 1}, + {0, NULL, 0}, + {12, embf_line_97, 9}, + {12, embf_line_98, 8}, + {12, embf_line_99, 5}, + {12, embf_line_100, 8}, + {12, embf_line_101, 8}, + {10, embf_line_102, 4}, + {12, embf_line_103, 11}, + {12, embf_line_104, 5}, + {10, embf_line_105, 2}, + {10, embf_line_106, 3}, + {12, embf_line_107, 3}, + {10, embf_line_108, 2}, + {12, embf_line_109, 10}, + {12, embf_line_110, 6}, + {12, embf_line_111, 8}, + {12, embf_line_112, 9}, + {12, embf_line_113, 8}, + {12, embf_line_114, 4}, + {12, embf_line_115, 9}, + {10, embf_line_116, 3}, + {12, embf_line_117, 5}, + {12, embf_line_118, 2}, + {12, embf_line_119, 9}, + {12, embf_line_120, 2}, + {12, embf_line_121, 8}, + {12, embf_line_122, 3}, + {12, embf_line_123, 6}, + {12, embf_line_124, 1}, + {12, embf_line_125, 6}, + {12, embf_line_126, 5}, + {0, NULL, 0} +}; Index: tags/1.1.4/src/geo.h =================================================================== --- tags/1.1.4/src/geo.h (nonexistent) +++ tags/1.1.4/src/geo.h (revision 818) @@ -0,0 +1,126 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_GEO_H +#define CAMV_GEO_H + + +#define G2D_INLINE RND_INLINE + +#include +#include +#include +#include + +typedef funcops rnd_coord_t g2d_coord_t; +typedef funcops double g2d_calc_t; +typedef funcops double g2d_offs_t; +typedef funcops double g2d_angle_t; + +#define G2D_COORD_MAX ((long)((1UL<<31)-1)) +#define G2D_COORD_TOL2 (0.01) + +G2D_INLINE g2d_coord_t g2d_round_coord(g2d_calc_t x_) +{ + double t, x = x_; + + if (x >= 0.0) { + t = ceil(x); + if (t - x > 0.5) + t -= 1.0; + return t; + } + + t = ceil(-x); + if ((t + x) > 0.5) + t -= 1.0; + return -t; +} + +G2D_INLINE g2d_coord_t g2d_round_coord_down(g2d_calc_t x) { return floor(x); } +G2D_INLINE g2d_coord_t g2d_round_coord_up(g2d_calc_t x) { return ceil(x); } + + +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_div_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a/b; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_mul_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a*b; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_sub_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a-b; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_add_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a+b; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_neg(g2d_calc_t a) { return -a; } +G2D_INLINE opfunc int g2d_calc_t_eq_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a==b; } +G2D_INLINE opfunc int g2d_calc_t_neq_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a!=b; } +G2D_INLINE opfunc int g2d_calc_t_lt_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return ab; } +G2D_INLINE opfunc int g2d_calc_t_gte_g2d_calc_t(g2d_calc_t a, g2d_calc_t b) { return a>=b; } +G2D_INLINE opfunc double double_convfrom_g2d_calc_t(g2d_calc_t a) { return a; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_convfrom_double(double a) { return a; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_convfrom_g2d_coord_t(g2d_coord_t a) { return a; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_convfrom_g2d_angle_t(g2d_angle_t a) { return a; } +G2D_INLINE opfunc g2d_calc_t g2d_calc_t_mul_g2d_offs_t(g2d_calc_t a, g2d_offs_t b) { return a*b; } + +G2D_INLINE opfunc g2d_coord_t g2d_coord_t_add_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return a+b; } +G2D_INLINE opfunc g2d_coord_t g2d_coord_t_sub_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return a-b; } +G2D_INLINE opfunc int g2d_coord_t_eq_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return a==b; } +G2D_INLINE opfunc int g2d_coord_t_neq_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return a!=b; } +G2D_INLINE opfunc int g2d_coord_t_lt_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return ab; } +G2D_INLINE opfunc int g2d_coord_t_gte_g2d_coord_t(g2d_coord_t a, g2d_coord_t b) { return a>=b; } +G2D_INLINE opfunc g2d_coord_t g2d_coord_t_neg(g2d_coord_t a) { return -a; } +G2D_INLINE opfunc g2d_coord_t g2d_coord_t_convfrom_g2d_calc_t(g2d_calc_t a) { return g2d_round_coord(a); } +G2D_INLINE opfunc g2d_coord_t g2d_coord_t_convfrom_int(int a) { return a; } + +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_add_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return a+b; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_sub_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return a-b; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_div_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return a/b; } +G2D_INLINE opfunc int g2d_angle_t_eq_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return a==b; } +G2D_INLINE opfunc int g2d_angle_t_lt_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return ab; } +G2D_INLINE opfunc int g2d_angle_t_gte_g2d_angle_t(g2d_angle_t a, g2d_angle_t b) { return a>=b; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_convfrom_double(double a) { return a; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_convfrom_g2d_calc_t(g2d_calc_t a) { return a; } +G2D_INLINE opfunc double double_convfrom_g2d_angle_t(g2d_angle_t a) { return a; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_neg(g2d_angle_t a) { return -a; } +G2D_INLINE opfunc g2d_angle_t g2d_angle_t_mul_g2d_offs_t(g2d_angle_t a, g2d_offs_t b) { return a*b; } + +G2D_INLINE opfunc int g2d_offs_t_eq_g2d_offs_t(g2d_offs_t a, g2d_offs_t b) { return a == b; } +G2D_INLINE opfunc int g2d_offs_t_lt_g2d_offs_t(g2d_offs_t a, g2d_offs_t b) { return a < b; } +G2D_INLINE opfunc int g2d_offs_t_lte_g2d_offs_t(g2d_offs_t a, g2d_offs_t b) { return a <= b; } +G2D_INLINE opfunc int g2d_offs_t_gt_g2d_offs_t(g2d_offs_t a, g2d_offs_t b) { return a > b; } +G2D_INLINE opfunc int g2d_offs_t_gte_g2d_offs_t(g2d_offs_t a, g2d_offs_t b) { return a >= b; } +G2D_INLINE opfunc g2d_offs_t g2d_offs_t_convfrom_g2d_angle_t(g2d_angle_t a) { return a; } +G2D_INLINE opfunc g2d_offs_t g2d_offs_t_convfrom_double(double a) { return a; } +G2D_INLINE opfunc g2d_offs_t g2d_offs_t_convfrom_g2d_calc_t(g2d_calc_t a) { return a; } + +G2D_INLINE g2d_calc_t g2d_sqrt(g2d_calc_t a) { return g2d_calc_t_convfrom_double(sqrt(double_convfrom_g2d_calc_t(a))); } +G2D_INLINE g2d_calc_t g2d_cos(g2d_angle_t a) { return g2d_calc_t_convfrom_double(cos(double_convfrom_g2d_angle_t(a))); } +G2D_INLINE g2d_calc_t g2d_sin(g2d_angle_t a) { return g2d_calc_t_convfrom_double(sin(double_convfrom_g2d_angle_t(a))); } +G2D_INLINE g2d_angle_t g2d_acos(g2d_calc_t a) { return g2d_angle_t_convfrom_double(acos(double_convfrom_g2d_calc_t(a))); } +G2D_INLINE g2d_angle_t g2d_asin(g2d_calc_t a) { return g2d_angle_t_convfrom_double(asin(double_convfrom_g2d_calc_t(a))); } +G2D_INLINE g2d_angle_t g2d_atan2(g2d_calc_t a, g2d_calc_t b) { return g2d_angle_t_convfrom_double(atan2(double_convfrom_g2d_calc_t(a), double_convfrom_g2d_calc_t(b))); } + +#endif Index: tags/1.1.4/src/gui_act.c =================================================================== --- tags/1.1.4/src/gui_act.c (nonexistent) +++ tags/1.1.4/src/gui_act.c (revision 818) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "build_run.h" +#include "data.h" + +static const char camv_acts_Quit[] = "Quit()"; +static const char camv_acth_Quit[] = "Quits the application."; +static fgw_error_t camv_act_Quit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + camv_rnd_quit_app(); + return FGW_SUCCESS; +} + +extern fgw_error_t rnd_gui_act_zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +TODO("Figure how to avoid copying this from librnd rnd_gui_acts_zoom") +const char camv_acts_Zoom[] = \ + "Zoom()\n" \ + "Zoom([+|-|=]factor)\n" \ + "Zoom(x1, y1, x2, y2)\n" \ + "Zoom(?)\n" \ + "Zoom(get)\n" \ + "Zoom(auto_first)\n"; +const char camv_acth_Zoom[] = "GUI zoom"; +fgw_error_t camv_act_Zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if ((argv[1].type & FGW_STR) == FGW_STR) { + if (strcmp(argv[1].val.str, "auto_first") == 0) { /* zoom to extent when the first file is loaded (called from the menu file) */ + if (camv.layers.used == 1) + return rnd_actionv_bin(RND_ACT_DESIGN, "rnd_zoom", res, 0, argv); + return 0; + } + } + return rnd_actionv_bin(RND_ACT_DESIGN, "rnd_zoom", res, argc, argv); +} + +#define get_layer(ly, idx, actname) \ + if ((argv[1].type & FGW_STR) == FGW_STR) { \ + const char *targets = NULL; \ + RND_ACT_CONVARG(1, FGW_STR, actname, targets = argv[1].val.str); \ + if ((targets[0] == '@') && (targets[1] == '\0')) { \ + idx = camv->lysel; \ + if ((idx < 0) || (idx >= camv->layers.used)) { \ + rnd_message(RND_MSG_ERROR, "No layer selected\n"); \ + RND_ACT_IRES(-1); \ + return FGW_SUCCESS; \ + } \ + } \ + else \ + RND_ACT_CONVARG(1, FGW_INT, actname, idx = argv[1].val.nat_int); \ + } \ + else \ + RND_ACT_CONVARG(1, FGW_INT, actname, idx = argv[1].val.nat_int); \ + \ + if ((idx < 0) || (idx >= camv->layers.used)) { \ + rnd_message(RND_MSG_ERROR, "No such layer\n"); \ + RND_ACT_IRES(-1); \ + return FGW_SUCCESS; \ + } \ + ly = camv->layers.array[idx]; + + + +static const char camv_acts_RotateLayer[] = "RotateLayer(@|idx, [deg])"; +static const char camv_acth_RotateLayer[] = "Rotates the layer addressed (@ for current) by deg degrees CCW. (The transformation is added to the current transformation matrix of the layer.)"; +static fgw_error_t camv_act_RotateLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + camv_design_t *camv = (camv_design_t *)hl; + double deg; + camv_layer_t *ly; + int idx; + + get_layer(ly, idx, RotateLayer); + + RND_ACT_CONVARG(2, FGW_DOUBLE, RotateLayer, deg = argv[2].val.nat_double); + + if (deg == 0) { + char *rds = rnd_hid_prompt_for(hl, "Please rotation in degrees", "15", "rotate layer"); + deg = strtod(rds, NULL); + free(rds); + if (deg == 0) + return -1; + } + + rnd_xform_mx_rotate(ly->mx, -deg); + ly->enable_mx = 1; + + RND_ACT_IRES(0); + return FGW_SUCCESS; +} + +static const char camv_acts_TranslateLayer[] = "TranslateLayer(@|idx, dx, dy)"; +static const char camv_acth_TranslateLayer[] = "Translates (moves) the layer addressed (@ for current) by dx and dy. (The transformation is added to the current transformation matrix of the layer.)"; +static fgw_error_t camv_act_TranslateLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + camv_design_t *camv = (camv_design_t *)hl; + rnd_coord_t dx, dy; + camv_layer_t *ly; + int idx; + + get_layer(ly, idx, TranslateLayer); + + RND_ACT_CONVARG(2, FGW_COORD_, TranslateLayer, dx = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD_, TranslateLayer, dy = fgw_coord(&argv[3])); + + rnd_xform_mx_translate(ly->mx, dx, dy); + ly->enable_mx = 1; + + RND_ACT_IRES(0); + return FGW_SUCCESS; +} + +static const char camv_acts_ScaleLayer[] = "ScaleLayer(@|idx, [sx, [sy]])"; +static const char camv_acth_ScaleLayer[] = "Scales the layer addressed (@ for current) by the factor of sx and sy. If only sx is specified, it is used as sy as well. (The transformation is added to the current transformation matrix of the layer.)"; +static fgw_error_t camv_act_ScaleLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + camv_design_t *camv = (camv_design_t *)hl; + double sx = 0, sy; + camv_layer_t *ly; + int idx; + + get_layer(ly, idx, ScaleLayer); + + RND_ACT_MAY_CONVARG(2, FGW_DOUBLE, ScaleLayer, sx = sy = argv[2].val.nat_double); + RND_ACT_MAY_CONVARG(3, FGW_DOUBLE, ScaleLayer, sy = argv[3].val.nat_double); + + if (sx == 0) { + char *scs = rnd_hid_prompt_for(hl, "Please specify scale factor", "1.5", "scale layer"); + sx = sy = strtod(scs, NULL); + free(scs); + if (sx == 0) + return -1; + } + + rnd_xform_mx_scale(ly->mx, sx, sy); + ly->enable_mx = 1; + + RND_ACT_IRES(0); + return FGW_SUCCESS; +} + +static const char camv_acts_ResetLayer[] = "ResetLayer(@|idx, sx[, sy])"; +static const char camv_acth_ResetLayer[] = "Reset the transformation matrix of the layer."; +static fgw_error_t camv_act_ResetLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static rnd_xform_mx_t ident = RND_XFORM_MX_IDENT; + rnd_design_t *hl = RND_ACT_DESIGN; + camv_design_t *camv = (camv_design_t *)hl; + camv_layer_t *ly; + int idx; + + get_layer(ly, idx, ResetLayer); + memcpy(ly->mx, ident, sizeof(ident)); + RND_ACT_IRES(0); + return FGW_SUCCESS; +} + +static rnd_action_t gui_action_list[] = { + {"Quit", camv_act_Quit, camv_acth_Quit, camv_acts_Quit}, + {"Zoom", camv_act_Zoom, camv_acth_Zoom, camv_acts_Zoom}, + {"RotateLayer", camv_act_RotateLayer, camv_acth_RotateLayer, camv_acts_RotateLayer}, + {"TranslateLayer", camv_act_TranslateLayer, camv_acth_TranslateLayer, camv_acts_TranslateLayer}, + {"ScaleLayer", camv_act_ScaleLayer, camv_acth_ScaleLayer, camv_acts_ScaleLayer}, + {"ResetLayer", camv_act_ResetLayer, camv_acth_ResetLayer, camv_acts_ResetLayer} +}; + +void gui_act_init(void) +{ + RND_REGISTER_ACTIONS(gui_action_list, NULL) +} + Index: tags/1.1.4/src/gui_act.h =================================================================== --- tags/1.1.4/src/gui_act.h (nonexistent) +++ tags/1.1.4/src/gui_act.h (revision 818) @@ -0,0 +1 @@ +void gui_act_init(void); Index: tags/1.1.4/src/main_act.c =================================================================== --- tags/1.1.4/src/main_act.c (nonexistent) +++ tags/1.1.4/src/main_act.c (revision 818) @@ -0,0 +1,267 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "config.h" +#include +#include "conf_core.h" +#include +#include +#include +#include "data.h" +#include "build_run.h" + +/* print usage lines */ +RND_INLINE void u(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); +} + +static const char camv_acts_PrintUsage[] = + "PrintUsage()\n" + "PrintUsage(plugin)"; + +static const char camv_acth_PrintUsage[] = "Print command line arguments of camv-rnd or a plugin loaded."; + +static int help0(void) +{ + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + + u("camv-rnd PCB related CAM file viewer, http://repo.hu/projects/camv-rnd"); + u("For more information, please read the topic help pages:"); + u(" camv-rnd --help topic"); + u("Topics are:"); + u(" invocation how to run camv-rnd"); + u(" main main/misc flags (affecting none or all plugins)"); + for (i = 0; hl[i]; i++) + if (hl[i]->usage != NULL) + u(" %-20s %s", hl[i]->name, hl[i]->description); + return 0; +} + +extern const char *camv_action_args[]; +static int help_main(void) { + const char **cs; + for(cs = camv_action_args; cs[2] != NULL; cs += RND_ACTION_ARGS_WIDTH) { + fprintf(stderr, "camv-rnd ["); + if (cs[0] != NULL) + fprintf(stderr, "-%s", cs[0]); + if ((cs[0] != NULL) && (cs[1] != NULL)) + fprintf(stderr, "|"); + if (cs[1] != NULL) + fprintf(stderr, "-%s", cs[1]); + fprintf(stderr, "] %s\n", cs[3]); + } + return 0; +} + +static int help_invoc(void) +{ + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + int n_printer = 0, n_exporter = 0; + + u("camv-rnd invocation:"); + u(""); + u("camv-rnd [main options] See --help main"); + u(""); + u("camv-rnd [generics] [--gui GUI] [gui options] interactive GUI"); + + u("Available GUI HIDs:"); + rnd_hid_print_all_gui_plugins(); + +/* + u("\ncamv-rnd [generics] -p [printing options] \tto print"); + u("Available printing hid%s:", n_printer == 1 ? "" : "s"); + for (i = 0; hl[i]; i++) + if (hl[i]->printer) + fprintf(stderr, "\t%-8s %s\n", hl[i]->name, hl[i]->description); + + u("\ncamv-rnd [generics] -x hid [export options] \tto export"); + u("Available export hid%s:", n_exporter == 1 ? "" : "s"); + for (i = 0; hl[i]; i++) + if (hl[i]->exporter) + fprintf(stderr, "\t%-8s %s\n", hl[i]->name, hl[i]->description); +*/ + + u("\nGenerics:"); + u("-c conf/path=value set the value of a configuration item (in RND_CFR_CLI)"); + u("-C conffile load config file (as RND_CFR_CLI; after all -c's)"); + + return 0; +} + +fgw_error_t camv_act_PrintUsage(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *topic = NULL, *subt = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, PrintUsage, topic = argv[1].val.str); + RND_ACT_IRES(0); + + u(""); + if (topic != NULL) { + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + + if (strcmp(topic, "invocation") == 0) return help_invoc(); + if (strcmp(topic, "main") == 0) return help_main(); + + for (i = 0; hl[i]; i++) { + if ((hl[i]->usage != NULL) && (strcmp(topic, hl[i]->name) == 0)) { + RND_ACT_MAY_CONVARG(2, FGW_STR, PrintUsage, subt = argv[2].val.str); + RND_ACT_IRES(hl[i]->usage(hl[i], subt)); + return 0; + } + } + fprintf(stderr, "No help available for %s\n", topic); + RND_ACT_IRES(-1); + return 0; + } + else + help0(); + return 0; +} + + +static const char camv_acts_PrintVersion[] = "PrintVersion()"; +static const char camv_acth_PrintVersion[] = "Print version."; +fgw_error_t camv_act_PrintVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", camv_rnd_get_info_program()); + RND_ACT_IRES(0); + return 0; +} + +static const char camv_acts_DumpVersion[] = "DumpVersion()"; +static const char camv_acth_DumpVersion[] = "Dump version in script readable format."; +fgw_error_t camv_act_DumpVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf(CAMV_VERS "\n"); + RND_ACT_IRES(0); + return 0; +} + +static const char camv_acts_PrintCopyright[] = "PrintCopyright()"; +static const char camv_acth_PrintCopyright[] = "Print copyright notice."; +fgw_error_t camv_act_PrintCopyright(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("camv-rnd - electronics-related CAM viewer\n"); + printf("Copyright (C) 2019..2021 Tibor 'Igor2' Palinkas\n"); + printf(" This program is free software; you can redistribute it and/or modify\n" + " it under the terms of the GNU General Public License as published by\n" + " the Free Software Foundation; either version 2 of the License, or\n" + " (at your option) any later version.\n\n"); + printf(" This program is distributed in the hope that it will be useful,\n" + " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + " GNU General Public License for more details.\n\n"); + printf(" You should have received a copy of the GNU General Public License\n" + " along with this program; if not, write to the Free Software\n" + " Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n"); + RND_ACT_IRES(0); + return 0; +} + +static const char camv_acts_PrintPaths[] = "PrintPaths()"; +static const char camv_acth_PrintPaths[] = "Print full paths and search paths."; +static void print_list(const rnd_conflist_t *cl) +{ + int n; + rnd_conf_listitem_t *ci; + const char *p; + + printf(" "); + rnd_conf_loop_list_str(cl, ci, p, n) { + printf("%c%s", (n == 0) ? '"' : ':', p); + } + printf("\"\n"); +} +fgw_error_t camv_act_PrintPaths(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + htsp_entry_t *e; + rnd_conf_fields_foreach(e) { + rnd_conf_native_t *n = e->value; + if ((strncmp(n->hash_path, "rc/path/", 8) == 0) && (n->type == RND_CFN_STRING) && (n->used == 1)) + printf("%-32s = %s\n", n->hash_path, n->val.string[0]); + } + RND_ACT_IRES(0); + return 0; +} + +/* Note: this can not be in librnd because of the app-specific setenvs */ +static const char camv_acts_System[] = "System(shell_cmd)"; +static const char camv_acth_System[] = "Run shell command"; +fgw_error_t camv_act_System(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char tmp[128]; + const char *cmd; + + RND_ACT_CONVARG(1, FGW_STR, System, cmd = argv[1].val.str); + RND_ACT_IRES(0); + +/* rnd_setenv("CAMV_RND_LAYER_FILE_NAME", RND_ACT_DESIGN->loadname == NULL ? "" : RND_ACT_DESIGN->loadname, 1);*/ + rnd_snprintf(tmp, sizeof(tmp), "%mm", camv.crosshair_x); + rnd_setenv("CAMV_RND_CROSSHAIR_X_MM", tmp, 1); + rnd_snprintf(tmp, sizeof(tmp), "%mm", camv.crosshair_y); + rnd_setenv("CAMV_RND_CROSSHAIR_Y_MM", tmp, 1); + RND_ACT_IRES(rnd_system(RND_ACT_DESIGN, cmd)); + return 0; +} + +/* Note: this can not be in librnd because of potential app-specific things */ +static const char camv_acts_ExecuteFile[] = "ExecuteFile(filename)"; +static const char camv_acth_ExecuteFile[] = "Run actions from the given file."; +/* DOC: executefile.html */ +fgw_error_t camv_act_ExecuteFile(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname; + + RND_ACT_CONVARG(1, FGW_STR, ExecuteFile, fname = argv[1].val.str); + RND_ACT_IRES(rnd_act_execute_file(RND_ACT_DESIGN, fname)); + return 0; +} + + +static rnd_action_t main_action_list[] = { + {"PrintUsage", camv_act_PrintUsage, camv_acth_PrintUsage, camv_acts_PrintUsage}, + {"PrintVersion", camv_act_PrintVersion, camv_acth_PrintVersion, camv_acts_PrintVersion}, + {"DumpVersion", camv_act_DumpVersion, camv_acth_DumpVersion, camv_acts_DumpVersion}, + {"PrintCopyright", camv_act_PrintCopyright, camv_acth_PrintCopyright, camv_acts_PrintCopyright}, + {"PrintPaths", camv_act_PrintPaths, camv_acth_PrintPaths, camv_acts_PrintPaths}, + {"System", camv_act_System, camv_acth_System, camv_acts_System}, + {"ExecActionFile", camv_act_ExecuteFile, camv_acth_ExecuteFile, camv_acts_ExecuteFile} +}; + +void camv_main_act_init2(void) +{ + RND_REGISTER_ACTIONS(main_action_list, NULL); +} Index: tags/1.1.4/src/menu.lht =================================================================== --- tags/1.1.4/src/menu.lht (nonexistent) +++ tags/1.1.4/src/menu.lht (revision 818) @@ -0,0 +1,205 @@ +ha:rnd-menu-v1 { + li:mouse { + li:left { + li:press = { Mode(Notify) } + li:press-shift = { Mode(Notify) } + li:press-ctrl = { Mode(Notify) } + li:release = { Mode(Release) } + li:release-shift = { Mode(Release) } + li:release-ctrl = { Mode(Release) } + } + li:middle { + li:press = { Pan(1) } + li:release = { Pan(0) } + } + li:right { + li:press = { Mode(Stroke) } + li:release = { Mode(Release); Popup(popup-obj, obj-type) } + li:shift-release = { Popup(popup-obj-misc) } + li:press-ctrl = { Display(CycleCrosshair) } + } + li:scroll-up { + li:press = { Zoom(0.8) } + li:press-shift = { Scroll(up) } + li:press-ctrl = { Scroll(left) } + } + li:scroll-down { + li:press = { Zoom(1.25) } + li:press-shift = { Scroll(down) } + li:press-ctrl = { Scroll(right) } + } + } + + # List of tool names for the toolbar. + # Do not specify keys here, they are specified in the menu; the GUI will + # not pick up keys from this subtree. There's also no action here: the + # plugin handling this subtree will always pick the tool. + li:toolbar_static { + ha:mline {tip={linear measurement}} + ha:mobj {tip={object measurement (prints to message log)}} + ha:arrow {tip={switch to arrow mode}} + } + + li:main_menu { + ### File Menu + ha:File { + li:submenu { + ha:New = { li:a={{f;n}; {Ctrln};}; action=Layer(DelAll) } + ha:Load... = { a={f;o}; action={Load(); Zoom(auto_first);} } + ha:Save design... = { a={f;s}; action=Save(); tip="Save all layers of the desig into a file that can be loaded later"} + - + ha:Loader configuration { + li:submenu { + ha:Assume laser cut on g-code = { checked=plugins/import_gcode/laser; action=conf(toggle, plugins/import_gcode/laser, design) } + } + } + - + ha:Print drawing... = { a={f;p}; action=Print()} + ha:Export drawing... = { a={f;e}; action=ExportDialog()} + - + ha:Preferences... = { a={i;c;p}; action=preferences} + - + ha:Quit = { a={f;q}; action=Quit() } + } + } + + ha:View { + li:submenu { + ha:Grid { + li:submenu { + ha:Enable visible grid = { a={g; v}; checked=editor/draw_grid; action=conf(toggle, editor/draw_grid, design) } + ha:Enable local grid = { a={g; l}; checked=editor/local_grid/enable; action=conf(toggle, editor/local_grid/enable, design) } + ha:Grid units { + li:submenu { + ha:mil = { a={g; i}; checked=ChkGridUnits(mil); action=SetUnits(mil); update_on={editor/grid_unit} } + ha:mm = { a={g; m}; checked=ChkGridUnits(mm); action=SetUnits(mm); update_on={editor/grid_unit} } + } + } + ha:Grid size = { + li:submenu { + ha:No Grid = { checked=ChkGridSize(none); action=SetGrid(1); update_on={editor/grid} } + - + @grid + - + ha:Previous grid = { li:a={{g; b};{[};}; action=Grid(down) } + ha:Next grid = { li:a={{g; f};{]};}; action=Grid(up) } + - + ha:Grid *2 = { a={g; d}; action=SetGrid(*2) } + ha:Grid /2 = { a={g; h}; action=SetGrid(/2) } + ha:Grid -5mil = { action=SetGrid(-5,mil) } + ha:Grid +5mil = { action=SetGrid(+5,mil) } + ha:Grid -0.05mm = { action=SetGrid(-0.05,mm) } + ha:Grid +0.05mm = { action=SetGrid(+0.05,mm) } + } + } + ha:Grid properties = { + li:submenu { + ha:Enable local grid = { checked=editor/local_grid/enable; action=conf(toggle, editor/local_grid/enable, design) } + - + ha:local grid radius 4 = { checked={conf(iseq, editor/local_grid/radius, 4)}; li:action={conf(set, editor/local_grid/radius, 4, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 8 = { checked={conf(iseq, editor/local_grid/radius, 8)}; li:action={conf(set, editor/local_grid/radius, 8, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 16 = { checked={conf(iseq, editor/local_grid/radius, 16)}; li:action={conf(set, editor/local_grid/radius, 16, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 32 = { checked={conf(iseq, editor/local_grid/radius, 32)}; li:action={conf(set, editor/local_grid/radius, 32, design); conf(set, editor/local_grid/enable, 1, design) } update_on={} } + - + ha:sparse global grid = { checked=editor/global_grid/sparse; action=conf(toggle, editor/global_grid/sparse, design) } + ha:global grid density 4 = { checked={conf(iseq, editor/global_grid/min_dist_px, 4)}; li:action={conf(set, editor/global_grid/min_dist_px, 4, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 8 = { checked={conf(iseq, editor/global_grid/min_dist_px, 8)}; li:action={conf(set, editor/global_grid/min_dist_px, 8, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 16 = { checked={conf(iseq, editor/global_grid/min_dist_px, 16)}; li:action={conf(set, editor/global_grid/min_dist_px, 16, design); conf(set, editor/local_grid/enable, 0, design) } update_on={} } + } + } + ha:Realign grid = { a={g; r}; action={ GetXY(Click to set the grid origin); Display(ToggleGrid) } } + } + } + ha:Current layer { + li:submenu { + ha:Move up { li:a={{l;u}; {l;Up};}; action=Layer(up) } + ha:Move down { li:a={{l;d}; {l;Down};}; action=Layer(down) } + ha:Move to top { li:a={{l;t}; {l;Page_Up};}; action=Layer(top) } + ha:Move to bottom { li:a={{l;b}; {l;Page_Down};}; action=Layer(bottom) } + ha:Add from file... { li:a={{l;a}; {l;+};}; action=Load(Layer) } + ha:Remove { li:a={{l;r}; {l;-};}; action=Layer(del) } + } + } + ha:Reverse layer order { li:a={{l;o};}; action=SwapSides(-, S) } + ha:Zoom { + li:submenu { + ha:Zoom In 20% = { li:a={{z;z;}; {+};} action=Zoom(-1.2) } + ha:Zoom Out 20% = { li:a={{z;x;}; {-};} action=Zoom(+1.2) } + ha:Zoom In 2X = { action=Zoom(-2) } + ha:Zoom Out 2X = { action=Zoom(+2) } + ha:Zoom to 0.1mil/px = { action={Zoom(=0.1mil)} } + ha:Zoom to 0.01mm/px = { action={Zoom(=0.01mm)} } + ha:Zoom to 1mil/px = { action={Zoom(=1mil)} } + ha:Zoom to 0.05mm/px = { action={Zoom(=0.05mm)} } + ha:Zoom to 2.5mil/px = { action={Zoom(=2.5mil)} } + ha:Zoom to 0.1mm/px = { action={Zoom(=0.1mm)} } + ha:Zoom to 10mil/px = { action={Zoom(=10mil)} } + ha:Zoom In 20% and center = { li:action={Zoom(-1.2); Center()} } + ha:Zoom Out 20% and center= { li:action={Zoom(+1.2); Center()} } + - + ha:Zoom Extents = { li:a={{z;e;}; {v;f};}; action=Zoom() } + ha:Zoom to selection = { a={z;s;}; action=ZoomTo(selected) } + ha:Zoom to found = { a={z;f;}; action=ZoomTo(found) } + - + ha:Flip up/down = { checked=editor/view/flip_y; a=Tab; action=SwapSides(V, S) } + ha:Flip left/right = { checked=editor/view/flip_x; a=ShiftTab; action=SwapSides(H, S) } + ha:Spin 180 degrees = { a=CtrlTab; action=SwapSides(R) } + - + ha:Center cursor = { a={v; c} action=Center() } + } + } + } + } + + ha:Plugins { + li:submenu { + ha:feature plugins = { + # submenu dedicated for feature plugins to register their menu items + li:submenu { + @feature_plugins + } + } + ha:script = { + # submenu dedicated for user scripts to register their menu items + li:submenu { + @scripts + } + } + ha:Manage plugins... = { a={p;m;p;}; action=ManagePlugins() } + ha:Manage scripts... = { a={p;m;s;}; action=BrowseScripts() } + } + } # Plugins + + ha:Window { + li:submenu { + ha:Message Log = { a={w;m}; action=LogDialog() } + ha:Command Entry = { li:a={a={w;c}; {:};} action=Command() } + } + } + + ha:Help { + li:submenu { + ha:About = { action=About() } + } + } + } #main_menu + + li:popups { +# context sensitive right click: popup per object type under the cursor + + ha:layer { + li:submenu { + ha:Move up { action=Layer(up) } + ha:Move down { action=Layer(down) } + ha:Move to top { action=Layer(top) } + ha:Move to bottom { action=Layer(bottom) } + - + ha:Add from file... { action=Load(Layer) } + ha:Remove { action=Layer(del) } + - + ha:Edit properties... { action=LayerDialog() } + } + } + } #popups + +} # root Index: tags/1.1.4/src/obj_any.c =================================================================== --- tags/1.1.4/src/obj_any.c (nonexistent) +++ tags/1.1.4/src/obj_any.c (revision 818) @@ -0,0 +1,50 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include "obj_any.h" + +void camv_obj_add_to_layer(camv_layer_t *ly, camv_any_obj_t *obj) +{ + assert(obj->proto.parent_layer == NULL); + assert(obj->proto.parent_obj == NULL); + obj->proto.parent_layer = ly; + camv_rtree_insert(&ly->objs, obj, camv_obj_bbox(obj)); +} + + +camv_any_obj_t *camv_obj_dup(const camv_any_obj_t *src) +{ + camv_any_obj_t *dst = src->proto.calls->alloc(); + src->proto.calls->copy(dst, src); + dst->proto.parent_layer = NULL; + dst->proto.parent_obj = NULL; + return dst; +} + Index: tags/1.1.4/src/obj_any.h =================================================================== --- tags/1.1.4/src/obj_any.h (nonexistent) +++ tags/1.1.4/src/obj_any.h (revision 818) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_ANY_H +#define CAMV_OBJ_ANY_H + +#include + +#include "camv_typedefs.h" +#include "data.h" +#include "obj_common.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_poly.h" +#include "obj_grp.h" +#include "obj_text.h" + +typedef struct camv_proto_s { + CAMV_ANY_PRIMITIVE_FIELDS; +} camv_proto_t; + +union camv_any_obj_u { + camv_proto_t proto; + camv_arc_t arc; + camv_line_t line; + camv_poly_t poly; + camv_grp_t grp; + camv_text_t text; +}; + +void camv_obj_add_to_layer(camv_layer_t *ly, camv_any_obj_t *obj); + +/* Allocate a new object and copy all fields from src, except for parent data */ +camv_any_obj_t *camv_obj_dup(const camv_any_obj_t *src); + +RND_INLINE camv_layer_t *camv_obj_parent_layer(const camv_any_obj_t *obj); +RND_INLINE camv_design_t *camv_obj_parent_design(const camv_any_obj_t *obj); +RND_INLINE camv_rtree_box_t *camv_obj_bbox(camv_any_obj_t *obj); + +/*** implementation (inlines) ***/ + +RND_INLINE camv_layer_t *camv_obj_parent_layer(const camv_any_obj_t *obj) +{ + while(obj->proto.parent_obj != NULL) obj = obj->proto.parent_obj; + return obj->proto.parent_layer; +} + +RND_INLINE camv_design_t *camv_obj_parent_design(const camv_any_obj_t *obj) +{ + camv_layer_t *ly = camv_obj_parent_layer(obj); + if (ly == NULL) + return NULL; + return ly->parent; +} + +RND_INLINE camv_rtree_box_t *camv_obj_bbox(camv_any_obj_t *obj) +{ + if (!obj->proto.bbox_valid) + obj->proto.calls->bbox(obj); + assert(obj->proto.bbox_valid); + return &obj->proto.bbox; +} + +RND_INLINE void camv_obj_free(camv_any_obj_t *obj) +{ + obj->proto.calls->free_fields(obj); + free(obj); +} + +#endif Index: tags/1.1.4/src/obj_arc.c =================================================================== --- tags/1.1.4/src/obj_arc.c (nonexistent) +++ tags/1.1.4/src/obj_arc.c (revision 818) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "obj_arc.h" +#include "obj_any.h" + +#include +#include "geo.h" +#include +#include + +static void camv_arc_free_fields(camv_any_obj_t *obj) +{ + /* no dynamic allocation */ +} + +static void camv_arc_draw(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx) +{ + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, obj->arc.thick); + if (mx != NULL) { + camv_layer_t *ly = obj->arc.parent_layer; + rnd_coord_t cx = rnd_xform_x((*mx), obj->arc.cx, obj->arc.cy); + rnd_coord_t cy = rnd_xform_y((*mx), obj->arc.cx, obj->arc.cy); + double rx = obj->arc.r * ly->mx_sx, ry = obj->arc.r * ly->mx_sy; + double start= obj->arc.start - ly->mx_rotdeg, delta = obj->arc.delta; + + rnd_render->draw_arc(gc, cx, cy, rx, ry, start, delta); + } + else + rnd_render->draw_arc(gc, obj->arc.cx, obj->arc.cy, obj->arc.r, obj->arc.r, obj->arc.start, obj->arc.delta); +} + +static void camv_arc_bbox(camv_any_obj_t *obj) +{ + g2d_sarc_t a; + g2d_box_t box; + + a.c.c.x = obj->arc.cx; + a.c.c.y = obj->arc.cy; + a.c.r = obj->arc.r; + a.c.start = (180-obj->arc.start) / RND_RAD_TO_DEG; + a.c.delta = -obj->arc.delta / RND_RAD_TO_DEG; + a.s.width = obj->arc.thick; + a.s.cap = G2D_CAP_ROUND; + box = g2d_sarc_bbox(&a); + + obj->arc.bbox.x1 = box.p1.x; obj->arc.bbox.y1 = box.p1.y; + obj->arc.bbox.x2 = box.p2.x; obj->arc.bbox.y2 = box.p2.y; + obj->arc.bbox_valid = 1; +} + + +static void camv_arc_copy(camv_any_obj_t *dst, const camv_any_obj_t *src) +{ + memcpy(&dst->arc, &src->arc, sizeof(camv_arc_t)); +} + +static void camv_arc_move(camv_any_obj_t *o, rnd_coord_t dx, rnd_coord_t dy) +{ + o->arc.cx += dx; + o->arc.cy += dy; + if (o->arc.bbox_valid) { + o->arc.bbox.x1 += dx; o->arc.bbox.y1 += dy; + o->arc.bbox.x2 += dx; o->arc.bbox.y2 += dy; + } +} + +static camv_any_obj_t *camv_arc_alloc(void) { return (camv_any_obj_t *)camv_arc_new(); } + +static int camv_arc_isc_box(const camv_any_obj_t *o, const camv_rtree_box_t *box) +{ + g2d_carc_t sa; + g2d_box_t bx; + g2d_vect_t ip[8]; + g2d_offs_t offs[8]; + + bx.p1.x = box->x1; bx.p1.y = box->y1; + bx.p2.x = box->x2; bx.p2.y = box->y2; + + sa.c.x = o->arc.cx; sa.c.y = o->arc.cy; + sa.r = o->arc.r; + sa.start = o->arc.start; sa.delta = o->arc.delta; +/* sa.thickness = o->arc.thick */ +TODO("geo: use sarc instead of carc"); + return g2d_iscp_carc_box(&sa, &bx, ip, offs); +} + + + +static const camv_objcalls_t camv_arc_calls = { + camv_arc_alloc, + camv_arc_free_fields, + camv_arc_draw, + camv_arc_bbox, + camv_arc_copy, + camv_arc_move, + camv_arc_isc_box +}; + +void camv_arc_init(camv_arc_t *arc) +{ + memset(arc, 0, sizeof(camv_arc_t)); + arc->type = CAMV_OBJ_ARC; + arc->calls = &camv_arc_calls; +} + +camv_arc_t *camv_arc_new(void) +{ + camv_arc_t *res = malloc(sizeof(camv_arc_t)); + camv_arc_init(res); + return res; +} + Index: tags/1.1.4/src/obj_arc.h =================================================================== --- tags/1.1.4/src/obj_arc.h (nonexistent) +++ tags/1.1.4/src/obj_arc.h (revision 818) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_ARC_H +#define CAMV_OBJ_ARC_H + +#include "obj_common.h" + +typedef struct camv_arc_s { + CAMV_ANY_PRIMITIVE_FIELDS; + rnd_coord_t cx, cy; /* center */ + rnd_coord_t r; /* radius */ + rnd_coord_t thick; + rnd_angle_t start, delta; +} camv_arc_t; + +void camv_arc_init(camv_arc_t *arc); +camv_arc_t *camv_arc_new(void); + +#endif Index: tags/1.1.4/src/obj_common.h =================================================================== --- tags/1.1.4/src/obj_common.h (nonexistent) +++ tags/1.1.4/src/obj_common.h (revision 818) @@ -0,0 +1,69 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_COMMON_H +#define CAMV_OBJ_COMMON_H + +#include +#include "camv_typedefs.h" +#include "rtree.h" +#include +#include + + +typedef enum camv_objtype_e { + CAMV_OBJ_invalid, + CAMV_OBJ_ARC, + CAMV_OBJ_LINE, + CAMV_OBJ_POLY, + CAMV_OBJ_GRP, + CAMV_OBJ_TEXT, + CAMV_OBJ_max +} camv_objtype_t; + +typedef struct camv_objcalls_s { + camv_any_obj_t *(*alloc)(void); + void (*free_fields)(camv_any_obj_t *obj); + void (*draw)(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx); + void (*bbox)(camv_any_obj_t *obj); + void (*copy)(camv_any_obj_t *dst, const camv_any_obj_t *src); + void (*move)(camv_any_obj_t *o, rnd_coord_t dx, rnd_coord_t dy); /* does not do any rtree administration, but bbox is updated if it was originally valid */ + int (*isc_box)(const camv_any_obj_t *o, const camv_rtree_box_t *box); + +} camv_objcalls_t; + +#define CAMV_ANY_PRIMITIVE_FIELDS \ + camv_rtree_box_t bbox; \ + camv_objtype_t type; \ + const camv_objcalls_t *calls; \ + camv_layer_t *parent_layer; \ + camv_any_obj_t *parent_obj; \ + unsigned bbox_valid:1 + + +/* NOTE: ->parent_layer is NULL for grp member objects and ->parent_obj is NULL for normal objects */ + +#endif Index: tags/1.1.4/src/obj_grp.c =================================================================== --- tags/1.1.4/src/obj_grp.c (nonexistent) +++ tags/1.1.4/src/obj_grp.c (revision 818) @@ -0,0 +1,128 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "obj_grp.h" +#include "obj_any.h" + +static void camv_grp_free_fields(camv_any_obj_t *obj) +{ + rnd_cardinal_t n; + camv_any_obj_t *gobj; + for(n = 0, gobj = obj->grp.objs; n < obj->grp.len; n++,gobj++) + gobj->proto.calls->free_fields(gobj); + free(obj->grp.objs); + obj->grp.objs = NULL; + obj->grp.len = 0; +} + +static void camv_grp_draw(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx) +{ + rnd_cardinal_t n; + camv_any_obj_t *gobj; + for(n = 0, gobj = obj->grp.objs; n < obj->grp.len; n++,gobj++) + gobj->proto.calls->draw(gobj, gc, mx); +} + +static void camv_grp_bbox(camv_any_obj_t *obj) +{ + rnd_cardinal_t n; + camv_any_obj_t *gobj; + + gobj = obj->grp.objs; + obj->grp.bbox = *camv_obj_bbox(gobj); + for(n = 1, gobj++; n < obj->grp.len; n++,gobj++) + camv_rtree_box_bump(&obj->grp.bbox, camv_obj_bbox(gobj)); + obj->arc.bbox_valid = 1; +} + +static void camv_grp_copy(camv_any_obj_t *dst, const camv_any_obj_t *src) +{ + rnd_cardinal_t n; + camv_any_obj_t *sobj, *dobj; + + memcpy(&dst->proto, &src->proto, sizeof(src->proto)); + dst->grp.len = src->grp.len; + dst->grp.objs = malloc(sizeof(camv_any_obj_t) * src->grp.len); + for(n = 0, sobj = src->grp.objs, dobj = dst->grp.objs; n < src->grp.len; n++,sobj++,dobj++) + sobj->proto.calls->copy(dobj, sobj); +} + +static void camv_grp_move(camv_any_obj_t *g, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_cardinal_t n; + camv_any_obj_t *o; + + for(n = 0, o = g->grp.objs; n < g->grp.len; n++,o++) + o->proto.calls->move(o, dx, dy); + + if (g->grp.bbox_valid) { + g->grp.bbox.x1 += dx; g->grp.bbox.y1 += dy; + g->grp.bbox.x2 += dx; g->grp.bbox.y2 += dy; + } +} + +static camv_any_obj_t *camv_grp_alloc(void) { return (camv_any_obj_t *)camv_grp_new(); } + +static int camv_grp_isc_box(const camv_any_obj_t *obj, const camv_rtree_box_t *box) +{ + rnd_cardinal_t n; + camv_any_obj_t *gobj; + + for(n = 0, gobj = obj->grp.objs; n < obj->grp.len; n++,gobj++) + if (gobj->proto.calls->isc_box(gobj, box)) + return 1; + + + return 0; +} + + +static const camv_objcalls_t camv_grp_calls = { + camv_grp_alloc, + camv_grp_free_fields, + camv_grp_draw, + camv_grp_bbox, + camv_grp_copy, + camv_grp_move, + camv_grp_isc_box +}; + +void camv_grp_init(camv_grp_t *grp) +{ + memset(grp, 0, sizeof(camv_grp_t)); + grp->type = CAMV_OBJ_GRP; + grp->calls = &camv_grp_calls; +} + +camv_grp_t *camv_grp_new(void) +{ + camv_grp_t *res = malloc(sizeof(camv_grp_t)); + camv_grp_init(res); + return res; +} + Index: tags/1.1.4/src/obj_grp.h =================================================================== --- tags/1.1.4/src/obj_grp.h (nonexistent) +++ tags/1.1.4/src/obj_grp.h (revision 818) @@ -0,0 +1,41 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_GRP_H +#define CAMV_OBJ_GRP_H + +#include "obj_common.h" + +struct camv_grp_s { + CAMV_ANY_PRIMITIVE_FIELDS; + rnd_cardinal_t len; + camv_any_obj_t *objs; /* allocated to as big as ->len */ +}; + +void camv_grp_init(camv_grp_t *grp); +camv_grp_t *camv_grp_new(void); + +#endif Index: tags/1.1.4/src/obj_line.c =================================================================== --- tags/1.1.4/src/obj_line.c (nonexistent) +++ tags/1.1.4/src/obj_line.c (revision 818) @@ -0,0 +1,128 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "obj_line.h" +#include "obj_any.h" +#include "geo.h" +#include + +#include + +static void camv_line_free_fields(camv_any_obj_t *obj) +{ + /* no dynamic allocation */ +} + +static void camv_line_draw(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx) +{ + rnd_coord_t x1, y1, x2, y2; + + if (mx != NULL) { + x1 = rnd_xform_x((*mx), obj->line.x1, obj->line.y1); y1 = rnd_xform_y((*mx), obj->line.x1, obj->line.y1); + x2 = rnd_xform_x((*mx), obj->line.x2, obj->line.y2); y2 = rnd_xform_y((*mx), obj->line.x2, obj->line.y2); + } + else { + x1 = obj->line.x1; y1 = obj->line.y1; + x2 = obj->line.x2; y2 = obj->line.y2; + } + + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, obj->line.thick); + rnd_render->draw_line(gc, x1, y1, x2, y2); +} + +static void camv_line_bbox(camv_any_obj_t *obj) +{ + rnd_coord_t th = obj->line.thick/2; + obj->line.bbox.x1 = MIN(obj->line.x1, obj->line.x2) - th; + obj->line.bbox.x2 = MAX(obj->line.x1, obj->line.x2) + th; + obj->line.bbox.y1 = MIN(obj->line.y1, obj->line.y2) - th; + obj->line.bbox.y2 = MAX(obj->line.y1, obj->line.y2) + th; + obj->line.bbox_valid = 1; +} + +static void camv_line_copy(camv_any_obj_t *dst, const camv_any_obj_t *src) +{ + memcpy(&dst->line, &src->line, sizeof(camv_line_t)); +} + +static void camv_line_move(camv_any_obj_t *o, rnd_coord_t dx, rnd_coord_t dy) +{ + o->line.x1 += dx; + o->line.x2 += dx; + o->line.y1 += dy; + o->line.y2 += dy; + if (o->line.bbox_valid) { + o->line.bbox.x1 += dx; o->line.bbox.y1 += dy; + o->line.bbox.x2 += dx; o->line.bbox.y2 += dy; + } +} + +static camv_any_obj_t *camv_line_alloc(void) { return (camv_any_obj_t *)camv_line_new(); } + +static int camv_line_isc_box(const camv_any_obj_t *o, const camv_rtree_box_t *box) +{ + g2d_cline_t sl; + g2d_box_t bx; + +TODO("geo: use sline instead of cline"); + bx.p1.x = box->x1 - o->line.thick/2; bx.p1.y = box->y1 - o->line.thick/2; + bx.p2.x = box->x2 + o->line.thick/2; bx.p2.y = box->y2 + o->line.thick/2; + + sl.p1.x = o->line.x1; sl.p1.y = o->line.y1; + sl.p2.x = o->line.x2; sl.p2.y = o->line.y2; +/* sl.thickness = o->line.thickness */ + + return g2d_isc_cline_box(&sl, &bx); +} + + +static const camv_objcalls_t camv_line_calls = { + camv_line_alloc, + camv_line_free_fields, + camv_line_draw, + camv_line_bbox, + camv_line_copy, + camv_line_move, + camv_line_isc_box +}; + +void camv_line_init(camv_line_t *line) +{ + memset(line, 0, sizeof(camv_line_t)); + line->type = CAMV_OBJ_LINE; + line->calls = &camv_line_calls; +} + +camv_line_t *camv_line_new(void) +{ + camv_line_t *res = malloc(sizeof(camv_line_t)); + camv_line_init(res); + return res; +} + Index: tags/1.1.4/src/obj_line.h =================================================================== --- tags/1.1.4/src/obj_line.h (nonexistent) +++ tags/1.1.4/src/obj_line.h (revision 818) @@ -0,0 +1,41 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_LINE_H +#define CAMV_OBJ_LINE_H + +#include "obj_common.h" + +typedef struct camv_line_s { + CAMV_ANY_PRIMITIVE_FIELDS; + rnd_coord_t x1, y1, x2, y2; + rnd_coord_t thick; +} camv_line_t; + +void camv_line_init(camv_line_t *line); +camv_line_t *camv_line_new(void); + +#endif Index: tags/1.1.4/src/obj_poly.c =================================================================== --- tags/1.1.4/src/obj_poly.c (nonexistent) +++ tags/1.1.4/src/obj_poly.c (revision 818) @@ -0,0 +1,162 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include "obj_poly.h" +#include "obj_any.h" + +#include "geo.h" +#include + +static void camv_poly_free_fields(camv_any_obj_t *obj) +{ + vtc0_uninit(&obj->poly.points); + obj->poly.x = obj->poly.y = NULL; + obj->poly.len = 0; +} + +static void camv_poly_draw(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx) +{ + if (mx != NULL) { + static vtc0_t x, y; + long n; + if (obj->poly.len > x.alloced) { + vtc0_enlarge(&x, obj->poly.len); + vtc0_enlarge(&y, obj->poly.len); + } + for(n = 0; n < obj->poly.len; n++) { + x.array[n] = rnd_xform_x((*mx), obj->poly.x[n], obj->poly.y[n]); + y.array[n] = rnd_xform_y((*mx), obj->poly.x[n], obj->poly.y[n]); + } + rnd_render->fill_polygon(gc, obj->poly.len, x.array, y.array); + } + else + rnd_render->fill_polygon(gc, obj->poly.len, obj->poly.x, obj->poly.y); +} + +static void camv_poly_bbox(camv_any_obj_t *obj) +{ + rnd_cardinal_t n; + const rnd_coord_t *x, *y; + + x = obj->poly.x; + y = obj->poly.y; + obj->poly.bbox.x1 = obj->poly.bbox.x2 = *x; + obj->poly.bbox.y1 = obj->poly.bbox.y2 = *y; + for(x++, y++, n = 1; n < obj->poly.len; n++,x++,y++) { + if (*x < obj->poly.bbox.x1) obj->poly.bbox.x1 = *x; + if (*x > obj->poly.bbox.x2) obj->poly.bbox.x2 = *x; + if (*y < obj->poly.bbox.y1) obj->poly.bbox.y1 = *y; + if (*y > obj->poly.bbox.y2) obj->poly.bbox.y2 = *y; + } + obj->poly.bbox_valid = 1; +} + +static void camv_poly_copy(camv_any_obj_t *dst, const camv_any_obj_t *src) +{ + memcpy(&dst->proto, &src->proto, sizeof(src->proto)); + + dst->poly.points.array = NULL; + dst->poly.points.alloced = dst->poly.points.used = 0; + vtc0_resize(&dst->poly.points, src->poly.points.used); + memcpy(dst->poly.points.array, src->poly.points.array, src->poly.points.used * sizeof(rnd_coord_t)); + + dst->poly.len = src->poly.len; + dst->poly.x = dst->poly.points.array; + dst->poly.y = dst->poly.points.array+dst->poly.len; +} + +static void camv_poly_move(camv_any_obj_t *o, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_cardinal_t n; + + for(n = 0; n < o->poly.len; n++) { + o->poly.x[n] += dx; + o->poly.y[n] += dy; + } + if (o->poly.bbox_valid) { + o->poly.bbox.x1 += dx; o->poly.bbox.y1 += dy; + o->poly.bbox.x2 += dx; o->poly.bbox.y2 += dy; + } +} + +static camv_any_obj_t *camv_poly_alloc(void) { return (camv_any_obj_t *)camv_poly_new(); } + +int camv_poly_isc_box(const camv_any_obj_t *o, const camv_rtree_box_t *box) +{ + rnd_cardinal_t n; + g2d_box_t bx; + + bx.p1.x = box->x1; bx.p1.y = box->y1; + bx.p2.x = box->x2; bx.p2.y = box->y2; + + TODO("geo: check if any box point is within the poly"); + + /* check if any poly point is within the box */ + for(n = 0; n < o->poly.len; n++) { + g2d_vect_t pt; + pt.x = o->poly.x[n]; pt.y = o->poly.y[n]; + if (g2d_point_in_box(&bx, pt)) + return 1; + } + return 0; +} + +static const camv_objcalls_t camv_poly_calls = { + camv_poly_alloc, + camv_poly_free_fields, + camv_poly_draw, + camv_poly_bbox, + camv_poly_copy, + camv_poly_move, + camv_poly_isc_box +}; + +void camv_poly_init(camv_poly_t *poly) +{ + memset(poly, 0, sizeof(camv_poly_t)); + poly->type = CAMV_OBJ_POLY; + poly->calls = &camv_poly_calls; +} + +camv_poly_t *camv_poly_new(void) +{ + camv_poly_t *res = malloc(sizeof(camv_poly_t)); + camv_poly_init(res); + return res; +} + +void camv_poly_allocpts(camv_poly_t *poly, rnd_cardinal_t len) +{ + poly->len = len; + vtc0_resize(&poly->points, len*2); + poly->points.used = poly->points.alloced = len*2; + poly->x = poly->points.array; + poly->y = poly->points.array+len; +} Index: tags/1.1.4/src/obj_poly.h =================================================================== --- tags/1.1.4/src/obj_poly.h (nonexistent) +++ tags/1.1.4/src/obj_poly.h (revision 818) @@ -0,0 +1,53 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_POLY_H +#define CAMV_OBJ_POLY_H + +#include "obj_common.h" +#include + +typedef struct camv_poly_s { + CAMV_ANY_PRIMITIVE_FIELDS; + + rnd_coord_t *x; + rnd_coord_t *y; + rnd_cardinal_t len; + + /* internal */ + vtc0_t points; /* single allocation for both x and y; first all x coords, then all y coords; as large as ->len*2 */ +} camv_poly_t; + +void camv_poly_init(camv_poly_t *poly); +camv_poly_t *camv_poly_new(void); + +void camv_poly_allocpts(camv_poly_t *poly, rnd_cardinal_t len); + +/*** internal ***/ +int camv_poly_isc_box(const camv_any_obj_t *o, const camv_rtree_box_t *box); /* used by text */ + + +#endif Index: tags/1.1.4/src/obj_text.c =================================================================== --- tags/1.1.4/src/obj_text.c (nonexistent) +++ tags/1.1.4/src/obj_text.c (revision 818) @@ -0,0 +1,181 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2020,2023 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "obj_text.h" +#include "obj_any.h" +#include "conf_core.h" + +#include "geo.h" +#include +#include "obj_poly.h" + +#include +#include +#include +#include +#include + +static rnd_font_t embf_, *embf = &embf_, *font = &embf_; +double font_scale = 1.0; + +#include "font_internal.c" + +static void camv_text_free_fields(camv_any_obj_t *obj) +{ + free(obj->text.s); + obj->text.s = NULL; +} + +static void camv_text_draw_atom_cb(void *cb_ctx, const rnd_glyph_atom_t *a) +{ + rnd_hid_gc_t gc = cb_ctx; + long h; + + switch(a->type) { + case RND_GLYPH_LINE: + rnd_hid_set_line_width(gc, a->line.thickness); + rnd_render->draw_line(gc, a->line.x1, a->line.y1, a->line.x2, a->line.y2); + break; + case RND_GLYPH_ARC: + rnd_hid_set_line_width(gc, a->arc.thickness); + rnd_render->draw_arc(gc, a->arc.cx, a->arc.cy, a->arc.r, a->arc.r, a->arc.start, a->arc.delta); + break; + case RND_GLYPH_POLY: + h = a->poly.pts.used / 2; + rnd_render->fill_polygon(gc, h, &a->poly.pts.array[0], &a->poly.pts.array[h]); + break; + } +} + +static void camv_text_draw(camv_any_obj_t *obj, rnd_hid_gc_t gc, rnd_xform_mx_t *mx) +{ + rnd_font_draw_string(font, (unsigned char *)obj->text.s, obj->text.x + obj->text.dx, obj->text.y + obj->text.dy, font_scale, font_scale, obj->text.rot, RND_FONT_MIRROR_Y, 0, 0, 0, RND_FONT_TINY_HIDE, camv_text_draw_atom_cb, gc); +} + +static void camv_text_bbox(camv_any_obj_t *obj) +{ + int n; + obj->text.bbox.x1 = obj->text.bbox.y1 = RND_COORD_MAX; + obj->text.bbox.x2 = obj->text.bbox.y2 = -RND_COORD_MAX; + for(n = 0; n < 4; n++) { + if (obj->text.cx[n] < obj->text.bbox.x1) obj->text.bbox.x1 = obj->text.cx[n]; + if (obj->text.cx[n] > obj->text.bbox.x2) obj->text.bbox.x2 = obj->text.cx[n]; + if (obj->text.cy[n] < obj->text.bbox.y1) obj->text.bbox.y1 = obj->text.cy[n]; + if (obj->text.cy[n] > obj->text.bbox.y2) obj->text.bbox.y2 = obj->text.cy[n]; + } + obj->text.bbox_valid = 1; +} + +void camv_text_update(rnd_design_t *hidlib, camv_text_t *text, camv_layer_t *ly) +{ + rnd_coord_t cx[4], cy[4], w, h; + + /* measure width and height */ + rnd_font_string_bbox(cx, cy, font, (unsigned char *)text->s, 0, 0, font_scale, font_scale, 0, RND_FONT_MIRROR_Y, 0, 0); + w = cx[1] - cx[0]; + h = cy[0] - cy[3]; + + text->dx = -w/2; + text->dy = h*1.5; + + if (text->rot != 0) { + double rad = -text->rot / RND_RAD_TO_DEG; + rnd_rotate(&text->dx, &text->dy, 0, 0, cos(rad), sin(rad)); + } + + rnd_font_string_bbox(text->cx, text->cy, font, (unsigned char *)text->s, text->x + text->dx, text->y + text->dy, font_scale, font_scale, text->rot, RND_FONT_MIRROR_Y, 0, 0); + camv_text_bbox((camv_any_obj_t *)text); +} + +static void camv_text_copy(camv_any_obj_t *dst, const camv_any_obj_t *src) +{ + memcpy(&dst->text, &src->text, sizeof(camv_text_t)); + dst->text.s = rnd_strdup(src->text.s); +} + +static void camv_text_move(camv_any_obj_t *o, rnd_coord_t dx, rnd_coord_t dy) +{ + int n; + o->text.x += dx; + o->text.y += dy; + for(n = 0; n < 4; n++) { + o->text.cx[n] += dx; + o->text.cy[n] += dy; + } + if (o->text.bbox_valid) { + o->text.bbox.x1 += dx; o->text.bbox.y1 += dy; + o->text.bbox.x2 += dx; o->text.bbox.y2 += dy; + } +} + +static camv_any_obj_t *camv_text_alloc(void) { return (camv_any_obj_t *)camv_text_new(); } + +static int camv_text_isc_box(const camv_any_obj_t *o, const camv_rtree_box_t *box) +{ + camv_any_obj_t op; + rnd_coord_t xy[8]; + + op.poly.points.alloced = op.poly.points.used = 8; + op.poly.points.array = xy; + op.poly.x = xy; + op.poly.y = xy+4; + + return 0; + + TODO("TODO: text may be rotated; use rotated box; see sch-rnd text_isc_with_box() triangle tests"); + return camv_poly_isc_box(&op, box); +} + +static const camv_objcalls_t camv_text_calls = { + camv_text_alloc, + camv_text_free_fields, + camv_text_draw, + camv_text_bbox, + camv_text_copy, + camv_text_move, + camv_text_isc_box +}; + +void camv_text_init(camv_text_t *text) +{ + memset(text, 0, sizeof(camv_text_t)); + text->type = CAMV_OBJ_TEXT; + text->calls = &camv_text_calls; +} + +camv_text_t *camv_text_new(void) +{ + camv_text_t *res = malloc(sizeof(camv_text_t)); + camv_text_init(res); + return res; +} + +void camv_font_init(void) +{ + rnd_font_load_internal(embf, embf_font, sizeof(embf_font) / sizeof(embf_font[0]), embf_minx, embf_miny, embf_maxx, embf_maxy); +} Index: tags/1.1.4/src/obj_text.h =================================================================== --- tags/1.1.4/src/obj_text.h (nonexistent) +++ tags/1.1.4/src/obj_text.h (revision 818) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_OBJ_TEXT_H +#define CAMV_OBJ_TEXT_H + +#include "obj_common.h" +#include + +typedef struct camv_text_s { + CAMV_ANY_PRIMITIVE_FIELDS; + rnd_coord_t x, y; /* placement: specify center bottom point of text */ + double rot; /* in degrees */ + char *s; + + /* internal/cache */ + rnd_coord_t cx[4], cy[4]; /* 4 corners of the rotated bbox */ + rnd_coord_t dx, dy; /* offsets from x,y to librnd font renderer */ +} camv_text_t; + +void camv_text_init(camv_text_t *text); +camv_text_t *camv_text_new(void); +void camv_text_update(rnd_design_t *hidlib, camv_text_t *text, camv_layer_t *color_ly); /* called to re-render the pixmap after field changes */ + +#endif Index: tags/1.1.4/src/ocgen =================================================================== --- tags/1.1.4/src/ocgen (nonexistent) +++ tags/1.1.4/src/ocgen (revision 818) @@ -0,0 +1,23 @@ +#!/bin/sh + +awk ' +BEGIN { + print "# Generated by ./ocgen called from make dep - DO NOT EDIT THIS FILE" + print "" +} + +function ocgen(o) +{ + c=o + sub("[.]o$", ".c", c) + print o ": " c + print "\t$(CC) $(CFLAGS) -c -o " o, c + print "" +} + +{ + for(n = 1; n <= NF; n++) + ocgen($n) +} + +' \ No newline at end of file Property changes on: tags/1.1.4/src/ocgen ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/src/plug_io.c =================================================================== --- tags/1.1.4/src/plug_io.c (nonexistent) +++ tags/1.1.4/src/plug_io.c (revision 818) @@ -0,0 +1,223 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include +#include +#include + +#include "plug_io.h" + + +static vtp0_t camv_io; +static int camv_io_sorted = 0; + +static int cmp_io_prio(const void *v1, const void *v2) +{ + const camv_io_t *io1 = v1, *io2 = v2; + + if (io1->prio > io2->prio) + return 1; + return -1; +} + +static void sort_io(void) +{ + if (camv_io_sorted) + return; + qsort(camv_io.array, camv_io.used, sizeof(void *), cmp_io_prio); + camv_io_sorted = 1; +} + +void camv_io_reg(camv_io_t *io) +{ + vtp0_append(&camv_io, io); + camv_io_sorted = 0; +} + +void camv_io_unreg(camv_io_t *io) +{ + size_t n; + for(n = 0; n < camv_io.used; n++) { + if (camv_io.array[n] == io) { + vtp0_remove(&camv_io, n , 1); + return; + } + } +} + +static void post_load(camv_design_t *camv) +{ + camv_data_bbox(camv); + camv->hidlib.dwg.X1 = camv->bbox.x1; + camv->hidlib.dwg.Y1 = camv->bbox.y1; + camv->hidlib.dwg.X2 = camv->bbox.x2; + camv->hidlib.dwg.Y2 = camv->bbox.y2; +} + +int camv_io_load(camv_design_t *camv, const char *fn) +{ + const camv_io_t *io; + int n; + FILE *f; + + f = rnd_fopen(&camv->hidlib, fn, "rb"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open '%s' for read\n", fn); + return -1; + } + + sort_io(); + + for(n = 0; n < camv_io.used; n++) { + io = camv_io.array[n]; + if (io->load == NULL) + continue; + rewind(f); + if ((io->test_load == NULL) || (io->test_load(camv, fn, f) != 0)) { + int res; + rewind(f); + + rnd_event(&camv->hidlib, RND_EVENT_LOAD_PRE, "s", fn); + res = io->load(camv, fn, f); + rnd_event(&camv->hidlib, RND_EVENT_LOAD_POST, "si", fn, res); + + if (res == 0) { + fclose(f); + post_load(camv); + return 0; + } + } + } + + return -1; +} + +/*** save ***/ + +typedef struct { + int prio; + camv_io_t *io; +} prio_t; +#define GVT(x) vtpr_ ## x +#define GVT_ELEM_TYPE prio_t +#define GVT_SIZE_TYPE int +#define GVT_DOUBLING_THRS 32 +#define GVT_START_SIZE 8 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + +static int prio_cmp(const void *d1, const void *d2) +{ + const prio_t *p1 = d1, *p2 = d2; + if (p1->prio <= p2->prio) return 1; + return -1; +} + +typedef enum { + LIST_SAVE +#if 0 + LIST_EXPORT +#endif +} io_list_dir_t; + +static void camv_plug_io_list(vtpr_t *res, const char *fn, const char *fmt, camv_io_type_t type, io_list_dir_t dir) +{ + int n, p; + prio_t *pr; + + for(n = 0; n < vtp0_len(&camv_io); n++) { + camv_io_t *io = camv_io.array[n]; + if (io == NULL) continue; + switch(dir) { + case LIST_SAVE: + if (io->save_prio == NULL) continue; + p = io->save_prio(fn, fmt, type); + break; +#if 0 + case LIST_EXPORT: + if (io->export_prio == NULL) continue; + p = io->export_prio(fn, fmt, type); + break; +#endif + } + + if (p > 0) { + pr = vtpr_alloc_append(res, 1); + pr->prio = p; + pr->io = io; + } + } + qsort(res->array, vtpr_len(res), sizeof(prio_t), prio_cmp); +} + +int camv_save_design(camv_design_t *camv, const char *fn_, const char *fmt) +{ + vtpr_t prios; + int n, ret = -1, len; + char *fn, *ext = NULL; + + if ((fmt == NULL) || (*fmt == '\0')) + return -1; + + len = strlen(fn_); + fn = malloc(len+1); + memcpy(fn, fn_, len+1); + if (fn[len-1] == '*') + ext = fn + len - 1; + + vtpr_init(&prios); + camv_plug_io_list(&prios, fn, fmt, CSCH_IOTYP_DESIGN, LIST_SAVE); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + if (ext != NULL) { + if (pr->io->ext_save_design != NULL) + strcpy(ext, pr->io->ext_save_design); + else + *ext = '\0'; + break; + } + + rnd_event(&camv->hidlib, RND_EVENT_SAVE_PRE, "s", fmt); + ret = pr->io->save_design(camv, fn); + rnd_event(&camv->hidlib, RND_EVENT_SAVE_POST, "si", fmt, ret); + + if (ret == 0) + break; + } + + free(fn); + vtpr_uninit(&prios); + return ret; +} Index: tags/1.1.4/src/plug_io.h =================================================================== --- tags/1.1.4/src/plug_io.h (nonexistent) +++ tags/1.1.4/src/plug_io.h (revision 818) @@ -0,0 +1,57 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_RND_PLUG_IO +#define CAMV_RND_PLUG_IO + +#include +#include "data.h" + +typedef enum camv_io_type_s { /* bitfield so multiple detections (e.g. design-or-layer) can be handled */ + CSCH_IOTYP_DESIGN = 1, + CSCH_IOTYP_LAYER = 2 +} camv_io_type_t; + + +typedef struct camv_io_s { + const char *name; + int prio; /* the higher the better */ + int (*test_load)(camv_design_t *camv, const char *fn, FILE *f); /* returns non-zero if the file looks good for the plugin */ + int (*load)(camv_design_t *camv, const char *fn, FILE *f); + + int (*save_prio)(const char *fn, const char *fmt, camv_io_type_t type); + int (*save_design)(camv_design_t *camv, const char *fn); + const char *ext_save_design; + +} camv_io_t; + +void camv_io_reg(camv_io_t *io); +void camv_io_unreg(camv_io_t *io); +int camv_io_load(camv_design_t *camv, const char *fn); + +int camv_save_design(camv_design_t *camv, const char *fn, const char *fmt); + +#endif Index: tags/1.1.4/src/plug_io_act.c =================================================================== --- tags/1.1.4/src/plug_io_act.c (nonexistent) +++ tags/1.1.4/src/plug_io_act.c (revision 818) @@ -0,0 +1,113 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include +#include "event.h" + +#include "data.h" +#include "plug_io.h" +#include "plug_io_act.h" + +static const char *plug_io_cookie = "plug_io_act"; + +static const char camv_acts_LoadFrom[] = "LoadFrom(Layer|Project,filename[,format])"; +static const char camv_acth_LoadFrom[] = "Load project or layer data from a file."; +fgw_error_t camv_act_LoadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op, *name, *format = NULL; + + RND_ACT_CONVARG(1, FGW_STR, LoadFrom, op = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, LoadFrom, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadFrom, format = argv[3].val.str); + + if (rnd_strcasecmp(op, "layer") == 0) { + if (camv_io_load(&camv, name) != 0) { + rnd_message(RND_MSG_ERROR, "Can not load file '%s'\n", name); + RND_ACT_IRES(-1); + return 0; + } + rnd_event(&camv.hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + } + else if (rnd_strcasecmp(op, "project") == 0) { + TODO("the actual project load"); + rnd_message(RND_MSG_ERROR, "LoadFrom(project,...) not yet implemented\n"); + } + else + RND_ACT_FAIL(LoadFrom); + + RND_ACT_IRES(0); + return 0; +} + +static const char camv_acts_SaveTo[] = "SaveTo(design, filename[,format])"; +static const char camv_acth_SaveTo[] = "Save design to a file."; +fgw_error_t camv_act_SaveTo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + camv_design_t *camv = (camv_design_t *)hl; + const char *op, *name, *format = "tedax"; + + RND_ACT_CONVARG(1, FGW_STR, SaveTo, op = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SaveTo, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SaveTo, format = argv[3].val.str); + + if (rnd_strcasecmp(op, "design") == 0) { + if (camv_save_design(camv, name, format) != 0) { + rnd_message(RND_MSG_ERROR, "Can not save file '%s'\n", name); + RND_ACT_IRES(-1); + return 0; + } + } + else { + rnd_message(RND_MSG_ERROR, "Invalid first argument\n"); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t camv_plug_io_act_list[] = { + {"LoadFrom", camv_act_LoadFrom, camv_acth_LoadFrom, camv_acts_LoadFrom}, + {"SaveTo", camv_act_SaveTo, camv_acth_SaveTo, camv_acts_SaveTo} +}; + +void camv_plug_io_act_uninit(void) +{ + rnd_remove_actions_by_cookie(plug_io_cookie); +} + +void camv_plug_io_act_init(void) +{ + RND_REGISTER_ACTIONS(camv_plug_io_act_list, plug_io_cookie); +} Index: tags/1.1.4/src/plug_io_act.h =================================================================== --- tags/1.1.4/src/plug_io_act.h (nonexistent) +++ tags/1.1.4/src/plug_io_act.h (revision 818) @@ -0,0 +1,7 @@ +#include + +fgw_error_t camv_act_LoadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void camv_plug_io_act_init(void); +void camv_plug_io_act_uninit(void); + Index: tags/1.1.4/src/rtree.c =================================================================== --- tags/1.1.4/src/rtree.c (nonexistent) +++ tags/1.1.4/src/rtree.c (revision 818) @@ -0,0 +1,38 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include "rtree.h" + +#include +#include +#include +#include + Index: tags/1.1.4/src/rtree.h =================================================================== --- tags/1.1.4/src/rtree.h (nonexistent) +++ tags/1.1.4/src/rtree.h (revision 818) @@ -0,0 +1,44 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef CAMV_RTREE_H +#define CAMV_RTREE_H + +#include + +typedef long int camv_rtree_cardinal_t; +typedef rnd_coord_t camv_rtree_coord_t; + +/* Instantiate an rtree */ +#define RTR(n) camv_rtree_ ## n +#define RTRU(n) CAMV_RTREE_ ## n +#define camv_rtree_privfunc static +#define camv_rtree_size 6 +#define camv_rtree_stack_max 8192 + +#include + +#endif /* CAMV_RTREE_H */ Index: tags/1.1.4/src_3rd/opc89.h =================================================================== --- tags/1.1.4/src_3rd/opc89.h (nonexistent) +++ tags/1.1.4/src_3rd/opc89.h (revision 818) @@ -0,0 +1,16 @@ +#ifdef __OPC89__ + +/* Being compiled with opc89: use attributes to mark types and functions */ +# define funcops __attribute__((opc89_ops)) +# define opfunc __attribute__((opc89_opfunc)) + +/* make sure asserts are kept as is */ +#define assert(a) + +#else + +/* Being compiled with a c compiler: make opc marks invisible */ +# define funcops +# define opfunc + +#endif Index: tags/1.1.4/src_3rd =================================================================== --- tags/1.1.4/src_3rd (nonexistent) +++ tags/1.1.4/src_3rd (revision 818) Property changes on: tags/1.1.4/src_3rd ___________________________________________________________________ Added: svn:externals ## -0,0 +1 ## +gengeo2d -r300 svn://repo.hu/gengeo2d/trunk/gengeo2d Index: tags/1.1.4/src_plugins/Buildin.tmpasm =================================================================== --- tags/1.1.4/src_plugins/Buildin.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/Buildin.tmpasm (revision 818) @@ -0,0 +1,20 @@ +# tmpasm script for compiling a plugin_src/ module as a buildin +# Requires variables before the include: +# /local/rnd/mod basename of the module (e.g. autoplace) +# /local/rnd/mod/OBJS full path of all object files +# /local/rnd/mod/OBJS_C99 full path of all object files for non-c89 +# /local/rnd/mod/CONF config file name + +append /local/camv/buildin_pups [@@/local/rnd/mod@=@/local/rnd/mod@/@/local/rnd/mod@.pup@] {\n} + +append /local/camv/MOD_OBJS ?/local/rnd/mod/OBJS +append /local/camv/MOD_OBJS_C99 ?/local/rnd/mod/OBJS_C99 +append /local/camv/MOD_LDFLAGS /local/rnd/mod/LDFLAGS +append /local/camv/MOD_CFLAGS /local/rnd/mod/CFLAGS +append /local/camv/MOD_RULES [@ + +mod_@/local/rnd/mod@: all + +@] + +include /local/camv/tmpasm/common_enabled Index: tags/1.1.4/src_plugins/Common_enabled.tmpasm =================================================================== --- tags/1.1.4/src_plugins/Common_enabled.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/Common_enabled.tmpasm (revision 818) @@ -0,0 +1,82 @@ +# explicit rules: .y -> .c +# do not assume old yacc to work to different file names, do the generation +# in a separate directory to allow parallel compilation with -j +switch /local/rnd/mod/YACC + case {^$} end + default + foreach /local/n in /local/rnd/mod/YACC + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + if /local/camv/want_parsgen + then + append /local/rnd/RULES [@ +# yacc for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.y + cd @/local/dn@ && bison --defines=@/local/bn@.h --output=@/local/bn@.c --report-file=@/local/bn@.output -d @/local/bn@.y +@] + else + append /local/rnd/RULES [@ +# dummy yacc for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: + echo "skipping yacc..." +@] + end + end + end +end + +# explicit rules: .l -> .c +# do not assume old lex to work to different file names, do the generation +# in a separate directory to allow parallel compilation with -j +switch /local/rnd/mod/LEX + case {^$} end + default + foreach /local/n in /local/rnd/mod/LEX + if /local/camv/want_parsgen + then + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + append /local/rnd/RULES [@ +# lex for @/local/rnd/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.l + cd @/local/dn@ && flex --outfile=@/local/bn@.c --header-file=@/local/bn@.h @/local/bn@.l +@] + else + append /local/rnd/RULES [@ +# dummy lex for @/local/rnd/mod@ +@/local/n@.c: + echo "skipping flex..." +@] + end + end + end +end + +put /local/rnd/mod/enabled {1} + +include /local/camv/tmpasm/plugin_conf +include /local/camv/tmpasm/plugin_sphash +include /local/camv/tmpasm/plugin_intconf + +append /local/rnd/CLEANFILES ?/local/rnd/mod/CLEANFILES +append /local/rnd/DISTCLEANFILES ?/local/rnd/mod/DISTCLEANFILES + +put /local/rnd/mod/enabled {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod/YACC {} +put /local/rnd/mod/LEX {} +put /local/rnd/mod/SPHASH {} +put /local/rnd/mod/CLEANFILES {} +put /local/rnd/mod/DISTCLEANFILES {} +put /local/rnd/mod {} +put /local/rnd/mod/CONFFILE {} +put /local/rnd/mod/CONFVAR {} Index: tags/1.1.4/src_plugins/Disable.tmpasm =================================================================== --- tags/1.1.4/src_plugins/Disable.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/Disable.tmpasm (revision 818) @@ -0,0 +1,24 @@ +# tmpasm script for disable a plugin_src/ module +# Requires variables before the include: +# /local/rnd/mod/OBJS full path of all object files + +# append all objects to the source list used only for dependencies +# NOTE: .o suffixes will be replaced with .c before generating the dep +append /local/pcb/DEPSRCS ?/local/rnd/mod/OBJS +append /local/pcb/DEPSRCS ?/local/rnd/mod/OBJS_C99 + +put /local/rnd/mod/enabled {0} + +include /local/camv/tmpasm/plugin_conf +include /local/camv/tmpasm/plugin_sphash +include /local/camv/tmpasm/plugin_intconf + +put /local/rnd/mod/enabled {} +put /local/rnd/mod/OBJS {} +put /local/rnd/mod/OBJS_C99 {} +put /local/rnd/mod/CONF {} +put /local/rnd/mod/LDFLAGS {} +put /local/rnd/mod/CFLAGS {} +put /local/rnd/mod {} +put /local/rnd/mod/CONFFILE {} +put /local/rnd/mod/CONFVAR {} Index: tags/1.1.4/src_plugins/Plugin.tmpasm =================================================================== --- tags/1.1.4/src_plugins/Plugin.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/Plugin.tmpasm (revision 818) @@ -0,0 +1,49 @@ +# tmpasm script for compiling a plugin_src/ module as a plugin +# Requires variables before the include: +# /local/rnd/mod basename of the module (e.g. autoplace) +# /local/rnd/mod/OBJS full path of all object files +# /local/rnd/mod/OBJS_C99 full path of all object files for non-c89 + +# clean up input vars +uniq /local/rnd/mod/OBJS +uniq /local/rnd/mod/OBJS_C99 +uniq /local/rnd/mod/CFLAGS +uniq /local/rnd/mod/LDFLAGS +uniq /local/rnd/mod/LIBS + +# generate .c -> .o rules in /local/comp/output +put /local/comp/OBJS_C89 ?/local/rnd/mod/OBJS +put /local/comp/OBJS_C99 ?/local/rnd/mod/OBJS_C99 +put /local/comp/C89FLAGS [@ $(C89FLAGS) @/local/rnd/mod/CFLAGS@ @] +put /local/comp/C99FLAGS [@ $(CFLAGS) @/local/rnd/mod/CFLAGS@ @] +include /local/camv/tmpasm/comp_var + +append /local/pcb/all [@ $(PLUGIDIR)/@/local/rnd/mod@.so @] + +append /local/rnd/rules/install_ [@ + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so" "$(LIBDIR)/plugins/@/local/rnd/mod@.so" + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.pup" "$(LIBDIR)/plugins/@/local/rnd/mod@.pup"@] + +append /local/rnd/CLEANFILES [@ $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.pup @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ @] + +append /local/camv/MOD_RULES [@ + +### Module @/local/rnd/mod@: plugin ### + +$(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so: @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ + $(CC) -shared @cc/rdynamic@ -o $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so @/local/rnd/mod/OBJS@ @/local/rnd/mod/OBJS_C99@ $(LDFLAGS) @/local/rnd/mod/LDFLAGS@ + +mod_@/local/rnd/mod@: $(PLUGIDIR)/@/local/rnd/mod@.so + +$(PLUGIDIR)/@/local/rnd/mod@.so: $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so + $(MKDIR) $(PLUGIDIR) + $(CP) $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.so $(PLUGIDIR)/@/local/rnd/mod@.so + $(CP) $(PLUGDIR)/@/local/rnd/mod@/@/local/rnd/mod@.pup $(PLUGIDIR)/@/local/rnd/mod@.pup + +# module .c -> .o rules +@/local/comp/output@ + +### Module @/local/rnd/mod@ end ### +@] + +include /local/camv/tmpasm/common_enabled Index: tags/1.1.4/src_plugins/README =================================================================== --- tags/1.1.4/src_plugins/README (nonexistent) +++ tags/1.1.4/src_plugins/README (revision 818) @@ -0,0 +1 @@ +core plugins Index: tags/1.1.4/src_plugins/dialogs/Makefile =================================================================== --- tags/1.1.4/src_plugins/dialogs/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make Index: tags/1.1.4/src_plugins/dialogs/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/dialogs/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/Plug.tmpasm (revision 818) @@ -0,0 +1,13 @@ +put /local/rnd/mod {dialogs} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/dialogs/dialogs.o + $(PLUGDIR)/dialogs/dlg_about.o + $(PLUGDIR)/dialogs/dlg_layer.o + $(PLUGDIR)/dialogs/dlg_pref_apptab.o +@] + +switch /local/module/dialogs/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/dialogs/dialogs.c =================================================================== --- tags/1.1.4/src_plugins/dialogs/dialogs.c (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dialogs.c (revision 818) @@ -0,0 +1,96 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LIBRND_3_2_0 +#include +#endif + +#include "event.h" + +#include "dlg_about.h" +#include "dlg_layer.h" + +static const char *camv_dialogs_cookie = "camv_dialogs"; + +void camv_dialogs_layer_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + camv_layer_dlg_layer_chg_ev(hidlib, user_data, argc, argv); +} + +void camv_dialogs_layer_selected_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + camv_layer_dlg_layer_chg_ev(hidlib, user_data, argc, argv); +} + + +static rnd_action_t camv_dialogs_action_list[] = { +#if LIBRND_3_2_0 + {"PrintGUI", rnd_act_PrintDialog, rnd_acth_PrintDialog, rnd_acts_PrintDialog}, +#endif + {"About", camv_act_About, camv_acth_About, camv_acts_About}, + {"LayerDialog", camv_act_LayerDialog, camv_acth_LayerDialog, camv_acts_LayerDialog} +}; + +extern int camv_dlg_pref_tab; +extern void (*camv_dlg_pref_first_init)(pref_ctx_t *ctx, int tab); + +int pplg_check_ver_dialogs(int ver_needed) { return 0; } + +void pplg_uninit_dialogs(void) +{ + rnd_event_unbind_allcookie(camv_dialogs_cookie); + rnd_remove_actions_by_cookie(camv_dialogs_cookie); + rnd_dlg_pref_uninit(); +} + +int pplg_init_dialogs(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(camv_dialogs_action_list, camv_dialogs_cookie); + rnd_dlg_pref_init(camv_dlg_pref_tab, camv_dlg_pref_first_init); + + rnd_event_bind(CAMV_EVENT_LAYERS_CHANGED, camv_dialogs_layer_chg_ev, NULL, camv_dialogs_cookie); + rnd_event_bind(CAMV_EVENT_LAYER_SELECTED, camv_dialogs_layer_selected_ev, NULL, camv_dialogs_cookie); + + return 0; +} Index: tags/1.1.4/src_plugins/dialogs/dialogs.pup =================================================================== --- tags/1.1.4/src_plugins/dialogs/dialogs.pup (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dialogs.pup (revision 818) @@ -0,0 +1,8 @@ +$class gui +$short base dialogs +$long Standard viewer dialog boxes +$state works +$package lib-gui +default buildin +dep lib_hid_common +autoload 1 Index: tags/1.1.4/src_plugins/dialogs/dlg_about.c =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_about.c (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_about.c (revision 818) @@ -0,0 +1,121 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2018 Tibor 'Igor2' Palinkas (in pcb-rnd) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include + +#include +#include +#include +#include +#include + +#include "build_run.h" + +#include "dlg_about.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ +} about_ctx_t; + +about_ctx_t about_ctx; + +static void about_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + about_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(about_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + + +static void camv_rnd_dlg_about(void) +{ + const char *tabs[] = { "About camv-rnd", "Options", "Paths", "License", NULL }; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + htsp_entry_t *e; + gds_t s; + + if (about_ctx.active) + return; + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(about_ctx.dlg, tabs); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_LABEL(about_ctx.dlg, camv_rnd_get_info_program()); + RND_DAD_LABEL(about_ctx.dlg, camv_rnd_get_info_copyright()); + RND_DAD_LABEL(about_ctx.dlg, camv_rnd_get_info_websites(NULL)); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, /*RND_HATF_SCROLL |*/ /*RND_HATF_FRAME |*/ RND_HATF_EXPFILL); + RND_DAD_LABEL(about_ctx.dlg, camv_rnd_get_info_compile_options()); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(about_ctx.dlg); + + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_COMPFLAG(about_ctx.dlg, RND_HATF_SCROLL); + gds_init(&s); + for (e = htsp_first(&rnd_file_loaded); e; e = htsp_next(&rnd_file_loaded, e)) { + htsp_entry_t *e2; + rnd_file_loaded_t *cat = e->value; + RND_DAD_LABEL(about_ctx.dlg, cat->name); + gds_truncate(&s, 0); + for (e2 = htsp_first(&cat->data.category.children); e2; e2 = htsp_next(&cat->data.category.children, e2)) { + rnd_file_loaded_t *file = e2->value; + rnd_append_printf(&s, " %s\t%s\t%s\n", file->name, file->data.file.path, file->data.file.desc); + } + RND_DAD_LABEL(about_ctx.dlg, s.array); + } + gds_uninit(&s); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_BEGIN_VBOX(about_ctx.dlg); + RND_DAD_LABEL(about_ctx.dlg, camv_rnd_get_info_license()); + RND_DAD_END(about_ctx.dlg); + + RND_DAD_END(about_ctx.dlg); + RND_DAD_BUTTON_CLOSES(about_ctx.dlg, clbtn); + RND_DAD_END(about_ctx.dlg); + + /* set up the context */ + about_ctx.active = 1; + + RND_DAD_NEW("about", about_ctx.dlg, "About sch-rnd", &about_ctx, rnd_false, about_close_cb); +} + +const char camv_acts_About[] = "About()\n"; +const char camv_acth_About[] = "Present the about box"; +fgw_error_t camv_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + camv_rnd_dlg_about(); + RND_ACT_IRES(0); + return 0; +} Index: tags/1.1.4/src_plugins/dialogs/dlg_about.h =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_about.h (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_about.h (revision 818) @@ -0,0 +1,3 @@ +extern const char camv_acts_About[]; +extern const char camv_acth_About[]; +fgw_error_t camv_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.1.4/src_plugins/dialogs/dlg_layer.c =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_layer.c (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_layer.c (revision 818) @@ -0,0 +1,159 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include + +#include +#include + +#include "data.h" +#include "event.h" + +#include "dlg_layer.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int widx, wname, wcolor; + int active; /* already open - allow only one instance */ +} layer_ctx_t; + +layer_ctx_t layer_ctx; + +static void layer_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + layer_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(layer_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void layer_camv2dlg(layer_ctx_t *ctx) +{ + int lidx = rnd_actionva(&camv.hidlib, "Layer", "getidx", NULL); + rnd_hid_attr_val_t hv; + camv_layer_t *ly; + char tmp[32], *short_name; + + if ((lidx < 0) && (lidx >= camv.layers.used)) { + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wname, &hv); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wcolor, 0); + return; + } + + ly = camv.layers.array[lidx]; + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wcolor, 1); + + hv.str = tmp; + sprintf(tmp, "%d", lidx); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->widx, &hv); + + + short_name = ly->short_name; + if (short_name == NULL) { + short_name = strrchr(ly->name, '/'); + if (short_name == NULL) + short_name = ly->name; + else + short_name++; + } + + hv.str = short_name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wname, &hv); + + hv.clr = ly->color; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wcolor, &hv); +} + +static void layer_clr_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&camv.hidlib, "Layer", "setcolor", attr->val.clr.str, NULL); +} + +static void layer_name_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + layer_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *na = &ctx->dlg[ctx->wname]; + rnd_actionva(&camv.hidlib, "Layer", "rename", na->val.str, NULL); +} + +static void camv_rnd_dlg_layer(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (layer_ctx.active) + return; + + RND_DAD_BEGIN_VBOX(layer_ctx.dlg); + RND_DAD_COMPFLAG(layer_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(layer_ctx.dlg, 2); + RND_DAD_COMPFLAG(layer_ctx.dlg, RND_HATF_EXPFILL); + + RND_DAD_LABEL(layer_ctx.dlg, "Index:"); + RND_DAD_LABEL(layer_ctx.dlg, "-"); + layer_ctx.widx = RND_DAD_CURRENT(layer_ctx.dlg); + + RND_DAD_LABEL(layer_ctx.dlg, "Name:"); + RND_DAD_BEGIN_HBOX(layer_ctx.dlg); + RND_DAD_STRING(layer_ctx.dlg); + layer_ctx.wname = RND_DAD_CURRENT(layer_ctx.dlg); + RND_DAD_ENTER_CB(layer_ctx.dlg, layer_name_change_cb); + RND_DAD_BUTTON(layer_ctx.dlg, "set"); + RND_DAD_CHANGE_CB(layer_ctx.dlg, layer_name_change_cb); + RND_DAD_END(layer_ctx.dlg); + + RND_DAD_LABEL(layer_ctx.dlg, "Color:"); + RND_DAD_COLOR(layer_ctx.dlg); + layer_ctx.wcolor = RND_DAD_CURRENT(layer_ctx.dlg); + RND_DAD_CHANGE_CB(layer_ctx.dlg, layer_clr_change_cb); + + RND_DAD_END(layer_ctx.dlg); + RND_DAD_BUTTON_CLOSES(layer_ctx.dlg, clbtn); + RND_DAD_END(layer_ctx.dlg); + + /* set up the context */ + layer_ctx.active = 1; + + RND_DAD_NEW("layer", layer_ctx.dlg, "Layer properties", &layer_ctx, rnd_false, layer_close_cb); + + layer_camv2dlg(&layer_ctx); +} + +void camv_layer_dlg_layer_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (layer_ctx.active) + layer_camv2dlg(&layer_ctx); +} + + +const char camv_acts_LayerDialog[] = "LayerDialog()\n"; +const char camv_acth_LayerDialog[] = "Present the LayerDialog box on the currently selected layer"; +fgw_error_t camv_act_LayerDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + camv_rnd_dlg_layer(); + RND_ACT_IRES(0); + return 0; +} Index: tags/1.1.4/src_plugins/dialogs/dlg_layer.h =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_layer.h (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_layer.h (revision 818) @@ -0,0 +1,6 @@ +extern const char camv_acts_LayerDialog[]; +extern const char camv_acth_LayerDialog[]; +fgw_error_t camv_act_LayerDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void camv_layer_dlg_layer_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + Index: tags/1.1.4/src_plugins/dialogs/dlg_pref_apptab.c =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_pref_apptab.c (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_pref_apptab.c (revision 818) @@ -0,0 +1,39 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/cschem + * lead developer: email to cschem (at) igor2.repo.hu + * mailing list: cschem (at) list.repo.hu (send "subscribe") + */ + +/* The preferences dialog, application specific tabs */ + +#include "config.h" + +#include + +#undef PREF_TAB +#define PREF_TAB 0 +#include "dlg_pref_general.c" + +int camv_dlg_pref_tab = PREF_TAB; +void (*camv_dlg_pref_first_init)(pref_ctx_t *ctx, int tab) = PREF_INIT_FUNC; + Index: tags/1.1.4/src_plugins/dialogs/dlg_pref_general.c =================================================================== --- tags/1.1.4/src_plugins/dialogs/dlg_pref_general.c (nonexistent) +++ tags/1.1.4/src_plugins/dialogs/dlg_pref_general.c (revision 818) @@ -0,0 +1,96 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * Copied from pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2021 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/cschem + * lead developer: email to cschem (at) igor2.repo.hu + * mailing list: cschem (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, general tab */ + +#include "config.h" +#include + +static pref_confitem_t perf_backup[] = { + {"Import gcode as laser cut", "plugins/import_gcode/laser", 0, NULL}, + {"Layer alpha\n(for HIDs supporting alpha blending)", "appearance/layer_alpha", 0, NULL}, + {NULL, NULL, 0} +}; + +static pref_confitem_t perf_cli[] = { + {"Number of commands to\nremember in the\nhistory list", "plugins/lib_hid_common/cli_history/slots", 0, NULL}, + {NULL, NULL, 0} +}; + +static void pref_general_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_design_t *hl = rnd_gui->get_dad_design(hid_ctx); + pref_ctx_t *ctx = caller_data; + + if (rnd_pref_dlg2conf_pre(hl, ctx) == NULL) + return; + + rnd_pref_dlg2conf_table(ctx, perf_backup, attr); + rnd_pref_dlg2conf_table(ctx, perf_cli, attr); + + rnd_pref_dlg2conf_post(hl, ctx); +} + +void camv_dlg_pref_general_close(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + rnd_pref_conflist_remove(ctx, perf_backup); + rnd_pref_conflist_remove(ctx, perf_cli); +} + +void camv_dlg_pref_general_create(pref_ctx_t *ctx, rnd_design_t *dsg) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); +/* RND_DAD_LABEL(ctx->dlg, "(invent some title)");*/ + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_pref_create_conftable(ctx, perf_backup, pref_general_dlg2conf); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); +/* RND_DAD_LABEL(ctx->dlg, "Command line entry");*/ + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_pref_create_conftable(ctx, perf_cli, pref_general_dlg2conf); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} + +static const rnd_pref_tab_hook_t pref_general = { + "General", RND_PREFTAB_AUTO_FREE_DATA | RND_PREFTAB_NEEDS_ROLE, + NULL, camv_dlg_pref_general_close, + camv_dlg_pref_general_create, + NULL, NULL +}; + +static void camv_dlg_pref_general_init(pref_ctx_t *ctx, int tab) +{ + PREF_INIT(ctx, &pref_general); +} +#undef PREF_INIT_FUNC +#define PREF_INIT_FUNC camv_dlg_pref_general_init Index: tags/1.1.4/src_plugins/export_lpr/Makefile =================================================================== --- tags/1.1.4/src_plugins/export_lpr/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/export_lpr/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make mod_export_lpr Index: tags/1.1.4/src_plugins/export_lpr/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/export_lpr/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/export_lpr/Plug.tmpasm (revision 818) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_lpr} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_lpr/lpr.o +@] + +switch /local/module/export_lpr/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/export_lpr/export_lpr.pup =================================================================== --- tags/1.1.4/src_plugins/export_lpr/export_lpr.pup (nonexistent) +++ tags/1.1.4/src_plugins/export_lpr/export_lpr.pup (revision 818) @@ -0,0 +1,10 @@ +$class export +$short lpr exporter (printer) +$long Export to lpr (using export_ps to generate postscript) +$state works +$fmt-native no +$fmt-feature-w printer (using ps) +$package export-extra +default buildin +dep export_ps +autoload 1 Index: tags/1.1.4/src_plugins/export_lpr/lpr.c =================================================================== --- tags/1.1.4/src_plugins/export_lpr/lpr.c (nonexistent) +++ tags/1.1.4/src_plugins/export_lpr/lpr.c (revision 818) @@ -0,0 +1,45 @@ + /* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include + +#include "../export_ps/export_ps.h" + +int pplg_check_ver_export_lpr(int ver_needed) { return 0; } + +void pplg_uninit_export_lpr(void) +{ + rnd_lpr_uninit(); +} + +int pplg_init_export_lpr(void) +{ + return rnd_lpr_init(&ps_hid, ps_ps_init, ps_hid_export_to_file, NULL, NULL); +} Index: tags/1.1.4/src_plugins/export_png/Makefile =================================================================== --- tags/1.1.4/src_plugins/export_png/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/export_png/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make mod_export_png Index: tags/1.1.4/src_plugins/export_png/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/export_png/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/export_png/Plug.tmpasm (revision 818) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_png} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_png/export_png.o +@] + +switch /local/module/export_png/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/export_png/export_png.c =================================================================== --- tags/1.1.4/src_plugins/export_png/export_png.c (nonexistent) +++ tags/1.1.4/src_plugins/export_png/export_png.c (revision 818) @@ -0,0 +1,348 @@ + /* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * (based on pcb-rnd) + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "draw.h" +#include "export.h" + +static rnd_hid_t png_hid; + +const char *png_cookie = "png HID"; + +static rnd_drwpx_t pctx_, *pctx = &pctx_; + +static FILE *png_f; + +static const rnd_export_opt_t png_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_pngfile 0 + + {"dpi", "Scale factor (pixels/inch). 0 to scale to specified size", + RND_HATT_INTEGER, 0, 10000, {100, 0, 0}, 0}, +#define HA_dpi 1 + + {"x-max", "Maximum width (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_xmax 2 + + {"y-max", "Maximum height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_ymax 3 + + {"xy-max", "Maximum width and height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0}, +#define HA_xymax 4 + + {"monochrome", "Convert to monochrome", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_mono 5 + + {"fill-gray-threshold", "In monochrome, fill polygons with gray if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 6 + + {"use-alpha", "Make the background transparent", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_use_alpha 7 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 8 + + {"format", "Export file format", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, rnd_drwpx_filetypes}, +#define HA_filetype 9 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 10 +}; + +#define NUM_OPTIONS (sizeof(png_attribute_list)/sizeof(png_attribute_list[0])) + +static rnd_hid_attr_val_t png_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *png_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + if (n) + *n = NUM_OPTIONS; + return png_attribute_list; +} + +static const char *filename; +static rnd_box_t *bounds; +static double png_fill_gray_thrs; + + +static rnd_hid_attr_val_t *png_options; + +static void png_head(void) +{ + pctx->ymirror = 1; + rnd_drwpx_start(pctx); +} + +static void png_finish(FILE *f) +{ + rnd_drwpx_finish(pctx, f, png_options[HA_filetype].lng); +} + +void png_hid_export_to_file(rnd_design_t *hl, FILE *the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + rnd_box_t region; + rnd_hid_expose_ctx_t ctx; + double dtmp; + + png_f = the_file; + + ctx.design = hl; + region.X1 = hl->dwg.X1; + region.Y1 = hl->dwg.Y1; + region.X2 = hl->dwg.X2; + region.Y2 = hl->dwg.Y2; + + png_options = options; + bounds = ®ion; + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + png_fill_gray_thrs = dtmp * dtmp * 3; + + pctx->in_mono = options[HA_mono].lng; + png_head(); + + ctx.view = *bounds; + rnd_app.expose_main(&png_hid, &ctx, xform); +} + +static void png_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + rnd_design_t *hl = design; + rnd_xform_t xform = {0}; + FILE *f; + + rnd_drwpx_init(pctx, hl); + + if (!options) { + png_get_export_options(hid, 0, design, appspec); + options = png_values; + } + + filename = camv_export_filename(hl, options[HA_pngfile].str, ".png"); + + if (rnd_drwpx_set_size(pctx, NULL, options[HA_dpi].lng, options[HA_xmax].lng, options[HA_ymax].lng, options[HA_xymax].lng) != 0) { + rnd_drwpx_uninit(pctx); + goto error; + } + + if (rnd_drwpx_create(pctx, options[HA_use_alpha].lng) != 0) { + rnd_message(RND_MSG_ERROR, "png_do_export(): Failed to create bitmap of %d * %d returned NULL. Aborting export.\n", pctx->w, pctx->h); + rnd_drwpx_uninit(pctx); + goto error; + } + + f = rnd_fopen_askovr(hl, filename, "wb", NULL); + if (f == NULL) { + perror(filename); + rnd_drwpx_uninit(pctx); + goto error; + } + + png_hid_export_to_file(hl, f, options, &xform); + + png_finish(f); + if (f != NULL) + fclose(f); + + rnd_drwpx_uninit(pctx); + + error:; +} + +static int png_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, png_attribute_list, sizeof(png_attribute_list) / sizeof(png_attribute_list[0]), png_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int png_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + return 1; +} + +static void png_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_drwpx_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static rnd_color_t png_last_color; +static void png_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + png_last_color = *color; + rnd_drwpx_set_color(pctx, gc, color); +} + +static void png_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_drwpx_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static void png_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_drwpx_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void png_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + png_draw_line(gc, x1, y1, x2, y1); + png_draw_line(gc, x2, y1, x2, y2); + png_draw_line(gc, x2, y2, x1, y2); + png_draw_line(gc, x1, y2, x1, y1); +} + +static void png_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_drwpx_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void png_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_drwpx_fill_circle(pctx, gc, cx, cy, radius); +} + +static void png_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (pctx->in_mono) { + double intens2 = png_last_color.fr * png_last_color.fr + png_last_color.fg * png_last_color.fg + png_last_color.fb * png_last_color.fb; + if (intens2 >= png_fill_gray_thrs) { + rnd_color_t clr = png_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + pctx->in_mono = 0; + clr.r = clr.g = clr.b = avg; + rnd_drwpx_set_color(pctx, gc, &clr); + pctx->in_mono = 1; + } + } + + rnd_drwpx_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + + +static void png_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + png_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +#if 0 +static void png_draw_pixmap(rnd_hid_t *hid, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_pixmap_t *pixmap) +{ + rnd_drwpx_draw_pixmap(pctx, hid, cx, cy, sx, sy, pixmap); +} +#endif + +static int png_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\npng exporter command line arguments:\n\n"); + rnd_hid_usage(png_attribute_list, sizeof(png_attribute_list) / sizeof(png_attribute_list[0])); + fprintf(stderr, "\nUsage: camv-rnd [generic_options] -x png [png options] foo.gbr\n\n"); + return 0; +} + +int pplg_check_ver_export_png(int ver_needed) { return 0; } + +void pplg_uninit_export_png(void) +{ + rnd_export_remove_opts_by_cookie(png_cookie); + + if (rnd_drwpx_has_any_format()) + rnd_hid_remove_hid(&png_hid); +} + +int pplg_init_export_png(void) +{ + RND_API_CHK_VER; + + memset(&png_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&png_hid); + + png_hid.struct_size = sizeof(rnd_hid_t); + png_hid.name = "png"; + png_hid.description = "GIF/JPEG/PNG export"; + png_hid.exporter = 1; + + png_hid.get_export_options = png_get_export_options; + png_hid.do_export = png_do_export; + png_hid.parse_arguments = png_parse_arguments; + png_hid.set_layer_group = png_set_layer_group; + png_hid.make_gc = rnd_drwpx_make_gc; + png_hid.destroy_gc = rnd_drwpx_destroy_gc; + png_hid.set_drawing_mode = png_set_drawing_mode; + png_hid.set_color = png_set_color; + png_hid.set_line_cap = rnd_drwpx_set_line_cap; + png_hid.set_line_width = rnd_drwpx_set_line_width; + png_hid.set_draw_xor = rnd_drwpx_set_draw_xor; + png_hid.draw_line = png_draw_line; + png_hid.draw_arc = png_draw_arc; + png_hid.draw_rect = png_draw_rect; + png_hid.fill_circle = png_fill_circle; + png_hid.fill_polygon = png_fill_polygon; + png_hid.fill_polygon_offs = png_fill_polygon_offs; + png_hid.fill_rect = png_fill_rect; +/* png_hid.draw_pixmap = png_draw_pixmap;*/ + png_hid.argument_array = png_values; + + png_hid.usage = png_usage; + + if (rnd_drwpx_has_any_format()) { + rnd_hid_register_hid(&png_hid); + rnd_hid_load_defaults(&png_hid, png_attribute_list, NUM_OPTIONS); + } + return 0; +} Index: tags/1.1.4/src_plugins/export_png/export_png.pup =================================================================== --- tags/1.1.4/src_plugins/export_png/export_png.pup (nonexistent) +++ tags/1.1.4/src_plugins/export_png/export_png.pup (revision 818) @@ -0,0 +1,11 @@ +$class export +$short export sheets to png +$long png, jpeg and gif render +$state works +$fmt-native no +$fmt-feature-e png +$package export-gd +$extdeps librnd-pixmap +dep lib_exp_pixmap +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/export_ps/Makefile =================================================================== --- tags/1.1.4/src_plugins/export_ps/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make mod_export_ps Index: tags/1.1.4/src_plugins/export_ps/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/export_ps/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/Plug.tmpasm (revision 818) @@ -0,0 +1,12 @@ +put /local/rnd/mod {export_ps} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_ps/export_ps.o + $(PLUGDIR)/export_ps/ps.o + $(PLUGDIR)/export_ps/eps.o +@] + +switch /local/module/export_ps/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/export_ps/eps.c =================================================================== --- tags/1.1.4/src_plugins/export_ps/eps.c (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/eps.c (revision 818) @@ -0,0 +1,276 @@ +/* + This file is part of pcb-rnd and was part of gEDA/PCB but lacked proper + copyright banner at the fork. It probably has the same copyright as + gEDA/PCB as a whole in 2011. +*/ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "draw.h" +#include "export.h" + +#include "export_ps.h" + + +static rnd_hid_t eps_hid; + +static rnd_eps_t pctx_, *pctx = &pctx_; + +static const rnd_export_opt_t eps_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --eps-file +Name of the encapsulated postscript output file. Can contain a path. +@end ftable +%end-doc +*/ + {"eps-file", "Encapsulated Postscript output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_psfile 0 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --eps-scale +Scale EPS output by the parameter @samp{num}. +@end ftable +%end-doc +*/ + {"eps-scale", "EPS scale", + RND_HATT_REAL, 0, 100, {0, 0, 1.0}, 0}, +#define HA_scale 1 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@item --monochrome +Convert output to monochrome. +@end ftable +%end-doc +*/ + {"monochrome", "Convert to monochrome", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_mono 2 + + {"fill-gray-threshold", "In monochrome, fill polygons with gray if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 3 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 4 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 5 +}; + +#define NUM_OPTIONS (sizeof(eps_attribute_list)/sizeof(eps_attribute_list[0])) + +static rnd_hid_attr_val_t eps_values[NUM_OPTIONS]; + +static const rnd_export_opt_t *eps_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + if (n) + *n = NUM_OPTIONS; + return eps_attribute_list; +} + +static const char *filename; +static double eps_fill_gray_thrs; +static rnd_hid_attr_val_t *options_; + +void eps_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + rnd_box_t region, *bnds; + double dtmp; + rnd_hid_expose_ctx_t ctx; + + options_ = options; + + region.X1 = hl->dwg.X1; + region.Y1 = hl->dwg.Y1; + region.X2 = hl->dwg.X2; + region.Y2 = hl->dwg.Y2; + bnds = ®ion; + + rnd_eps_init(pctx, the_file, *bnds, options_[HA_scale].dbl, options[HA_mono].lng, 0); + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + eps_fill_gray_thrs = dtmp * dtmp * 3; + + if (pctx->outf != NULL) + rnd_eps_print_header(pctx, rnd_hid_export_fn(filename), 0, 1); + + ctx.design = hl; + ctx.view = *bnds; + rnd_app.expose_main(&eps_hid, &ctx, xform); + + rnd_eps_print_footer(pctx); + + options_ = NULL; +} + +static void eps_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + rnd_design_t *hl = design; + rnd_xform_t xform = {0}; + + if (!options) { + eps_get_export_options(hid, 0, design, appspec); + options = eps_values; + } + + filename = camv_export_filename(hl, options[HA_psfile].str, ".eps"); + pctx->outf = rnd_fopen_askovr(hl, filename, "w", NULL); + if (pctx->outf == NULL) { + perror(filename); + goto error; + } + + eps_hid_export_to_file(hl, pctx->outf, options, &xform); + + fclose(pctx->outf); + + error:; +} + +static int eps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, eps_attribute_list, sizeof(eps_attribute_list) / sizeof(eps_attribute_list[0]), ps_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int eps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + return 1; +} + +static void eps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_eps_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static rnd_color_t eps_last_color; +static void eps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + eps_last_color = *color; + rnd_eps_set_color(pctx, gc, color); +} + +static void eps_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_draw_rect(pctx, gc, x1, y1, x2, y2); +} + +static void eps_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void eps_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_eps_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void eps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_eps_fill_circle(pctx, gc, cx, cy, radius); +} + +static void eps_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (pctx->in_mono) { + double intens2 = eps_last_color.fr * eps_last_color.fr + eps_last_color.fg * eps_last_color.fg + eps_last_color.fb * eps_last_color.fb; + + if (intens2 >= eps_fill_gray_thrs) { + rnd_color_t clr = eps_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + clr.r = clr.g = clr.b = avg; + + pctx->in_mono = 0; + rnd_eps_set_color(pctx, gc, &clr); + pctx->in_mono = 1; + } + } + + rnd_eps_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + +static void eps_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + eps_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void eps_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_eps_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static int eps_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\neps exporter command line arguments:\n\n"); + rnd_hid_usage(eps_attribute_list, sizeof(eps_attribute_list) / sizeof(eps_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x eps [eps options] foo.pcb\n\n"); + return 0; +} + +void hid_eps_uninit() +{ + rnd_hid_remove_hid(&eps_hid); +} + +void hid_eps_init() +{ + memset(&eps_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&eps_hid); + + eps_hid.struct_size = sizeof(rnd_hid_t); + eps_hid.name = "eps"; + eps_hid.description = "Encapsulated Postscript"; + eps_hid.exporter = 1; + + eps_hid.get_export_options = eps_get_export_options; + eps_hid.do_export = eps_do_export; + eps_hid.parse_arguments = eps_parse_arguments; + eps_hid.set_layer_group = eps_set_layer_group; + eps_hid.make_gc = rnd_eps_make_gc; + eps_hid.destroy_gc = rnd_eps_destroy_gc; + eps_hid.set_drawing_mode = eps_set_drawing_mode; + eps_hid.set_color = eps_set_color; + eps_hid.set_line_cap = rnd_eps_set_line_cap; + eps_hid.set_line_width = rnd_eps_set_line_width; + eps_hid.set_draw_xor = rnd_eps_set_draw_xor; + eps_hid.draw_line = eps_draw_line; + eps_hid.draw_arc = eps_draw_arc; + eps_hid.draw_rect = eps_draw_rect; + eps_hid.fill_circle = eps_fill_circle; + eps_hid.fill_polygon = eps_fill_polygon; + eps_hid.fill_polygon_offs = eps_fill_polygon_offs; + eps_hid.fill_rect = eps_fill_rect; + eps_hid.set_crosshair = rnd_eps_set_crosshair; + eps_hid.argument_array = eps_values; + + eps_hid.usage = eps_usage; + + rnd_hid_register_hid(&eps_hid); + rnd_hid_load_defaults(&eps_hid, eps_attribute_list, NUM_OPTIONS); +} Index: tags/1.1.4/src_plugins/export_ps/export_ps.c =================================================================== --- tags/1.1.4/src_plugins/export_ps/export_ps.c (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/export_ps.c (revision 818) @@ -0,0 +1,54 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - ps export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include "config.h" + +#include + +#include +#include + +#include "export_ps.h" + +int pplg_check_ver_export_ps(int ver_needed) { return 0; } + +void pplg_uninit_export_ps(void) +{ + hid_ps_uninit(); + hid_eps_uninit(); +} + +int pplg_init_export_ps(void) +{ + RND_API_CHK_VER; + + hid_ps_init(); + hid_eps_init(); + + return 0; +} Index: tags/1.1.4/src_plugins/export_ps/export_ps.h =================================================================== --- tags/1.1.4/src_plugins/export_ps/export_ps.h (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/export_ps.h (revision 818) @@ -0,0 +1,12 @@ +/* required by lpr */ +extern rnd_hid_t ps_hid; +extern void ps_hid_export_to_file(rnd_design_t *dsg, FILE *, rnd_hid_attr_val_t *, rnd_xform_t *, void *); +void ps_ps_init(rnd_hid_t * hid); + +/* required for ps<->eps cross call */ +extern void hid_eps_init(); +extern void hid_eps_uninit(); +extern void hid_ps_init(); +extern void hid_ps_uninit(); +extern const char *ps_cookie; + Index: tags/1.1.4/src_plugins/export_ps/export_ps.pup =================================================================== --- tags/1.1.4/src_plugins/export_ps/export_ps.pup (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/export_ps.pup (revision 818) @@ -0,0 +1,11 @@ +$class export +$short export sheets to ps/eps +$long PostScript, Encapsulated PostScript exporter +$state works +$fmt-native no +$fmt-feature-e ps +$fmt-feature-e eps +$package export-vector +dep lib_exp_text +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/export_ps/ps.c =================================================================== --- tags/1.1.4/src_plugins/export_ps/ps.c (nonexistent) +++ tags/1.1.4/src_plugins/export_ps/ps.c (revision 818) @@ -0,0 +1,480 @@ +/* + This file is part of pcb-rnd and was part of gEDA/PCB but lacked proper + copyright banner at the fork. It probably has the same copyright as + gEDA/PCB as a whole in 2011. +*/ +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "draw.h" +#include "export.h" + +#include "export_ps.h" + +const char *ps_cookie = "ps HID"; + +static int ps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform); + +static const rnd_export_opt_t ps_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --psfile +Name of the postscript output file. Can contain a path. +@end ftable +%end-doc +*/ + {"psfile", "Postscript output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_psfile 0 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --fill-page +Scale output to make the sheet fit the page. +@end ftable +%end-doc +*/ + {"fill-page", "Scale drawing to fill page (default off)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_fillpage 1 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --ps-color +Postscript output in color. +@end ftable +%end-doc +*/ + {"ps-color", "Prints in color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_color 2 + + {"fill-gray-threshold", "If ps-color is not enabled, fill polygons with grey if color is lighter than this percentage (0 is black, 100 is white)", + RND_HATT_INTEGER, 0, 100, {80, 0, 0}, 0}, +#define HA_fill_gray_threshold 3 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex ps-invert +@item --ps-invert +Draw objects as white-on-black. +@end ftable +%end-doc +*/ + {"ps-invert", "Draw objects as white-on-black", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_psinvert 4 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --media +Size of the media, the postscript is fitted to. The parameter +@code{} can be any of the standard names for paper size: @samp{A0} +to @samp{A10}, @samp{B0} to @samp{B10}, @samp{Letter}, @samp{11x17}, +@samp{Ledger}, @samp{Legal}, @samp{Executive}, @samp{A-Size}, @samp{B-size}, +@samp{C-Size}, @samp{D-size}, @samp{E-size}, @samp{US-Business_Card}, +@samp{Intl-Business_Card}. +@end ftable +%end-doc +*/ + {"media", "media type", + RND_HATT_ENUM, 0, 0, {22, 0, 0}, rnd_medias}, +#define HA_media 5 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --scale +Scale value to compensate for printer sizing errors (1.0 = full scale). +@end ftable +%end-doc +*/ + {"scale", "Scale value to compensate for printer sizing errors (1.0 = full scale)", + RND_HATT_REAL, 0.01, 4, {0, 0, 1.00}, 0}, +#define HA_scale 6 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex multi-file +@item --multi-file +Produce multiple files, one per page, instead of a single multi page file. +@end ftable +%end-doc +*/ + {"multi-file", "Produce multiple files, one per page, instead of a single file", + RND_HATT_BOOL, 0, 0, {0, 0, 0.40}, 0}, +#define HA_multifile 7 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex show-toc +@item --show-toc +Generate Table of Contents +@end ftable +%end-doc +*/ + {"show-toc", "Print Table of Content (automatic decision unless explicitly changed)", + RND_HATT_BOOL, 0, 0, {2, 0, 0}, 0}, /* 2 means "auto" */ +#define HA_toc 8 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 9 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 10 +}; + +#define NUM_OPTIONS (sizeof(ps_attribute_list)/sizeof(ps_attribute_list[0])) + +/* All file-scope data is in global struct */ +static struct { + rnd_ps_t ps; + + rnd_bool multi_file; + double fill_gray_thrs; + + const char *filename; + rnd_hid_expose_ctx_t exps; + + rnd_hid_attr_val_t ps_values[NUM_OPTIONS]; + + int ovr_all; + int doing_prj; /* 1 if exporting a project */ + int had_page; /* 1 if we ever wrote a page */ +} global; + +static const rnd_export_opt_t *ps_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + if (n) + *n = NUM_OPTIONS; + return ps_attribute_list; +} + +static FILE *psopen(rnd_design_t *hl, const char *base, const char *which) +{ + FILE *ps_open_file; + char *buf, *suff, *buf2; + + if (base == NULL) /* cam, file name template case */ + return NULL; + + if (!global.multi_file) + return rnd_fopen_askovr(hl, base, "w", NULL); + + buf = (char *)malloc(strlen(base) + strlen(which) + 5); + + suff = (char *)strrchr(base, '.'); + if (suff) { + strcpy(buf, base); + buf2 = strrchr(buf, '.'); + sprintf(buf2, ".%s.%s", which, suff + 1); + } + else { + sprintf(buf, "%s.%s.ps", base, which); + } + ps_open_file = rnd_fopen_askovr(hl, buf, "w", &global.ovr_all); + free(buf); + return ps_open_file; +} + +/* This is used by other HIDs that use a postscript format, like lpr or eps. */ +void ps_hid_export_to_file(rnd_design_t *hl, FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform, void *appspec) +{ + double dtmp; + int toc; + + rnd_ps_init(&global.ps, hl, the_file, options[HA_media].lng, options[HA_fillpage].lng, options[HA_scale].dbl); + + /* generic ps config: extra conf from export params */ + global.ps.incolor = options[HA_color].lng; + global.ps.invert = options[HA_psinvert].lng; + + dtmp = (double)options[HA_fill_gray_threshold].lng / 100.0; + global.fill_gray_thrs = dtmp * dtmp * 3; + + if (the_file) + rnd_ps_start_file(&global.ps, "sch-rnd release: sch-rnd " CAMV_VERS); + + /* reset static vars */ + rnd_ps_use_gc(&global.ps, NULL); + + global.exps.design = hl; + global.exps.view.X1 = hl->dwg.X1; + global.exps.view.Y1 = hl->dwg.Y1; + global.exps.view.X2 = hl->dwg.X2; + global.exps.view.Y2 = hl->dwg.Y2; + + /* print ToC */ + switch(options[HA_toc].lng) { + case 0: toc = 0; break; /* explicit off */ + case 1: toc = 1; break; /* explicit on */ + default: toc = global.doing_prj; /* auto: use toc for project export, don't use toc for single sheet export */ + } + + global.had_page = 0; + if (!global.multi_file && toc) { + rnd_ps_begin_toc(&global.ps); + rnd_app.expose_main(&ps_hid, &global.exps, xform); + rnd_ps_end_toc(&global.ps); + global.had_page = 1; + } + + /* print page(s) */ + rnd_ps_begin_pages(&global.ps); + rnd_app.expose_main(&ps_hid, &global.exps, xform); + rnd_ps_end_pages(&global.ps); +} + +static void ps_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + rnd_design_t *hl = design; + FILE *fh; + rnd_xform_t xform = {0}; + + global.ovr_all = 0; + + if (!options) { + ps_get_export_options(hid, 0, design, appspec); + options = global.ps_values; + } + + global.multi_file = options[HA_multifile].lng; + global.filename = camv_export_filename(hl, options[HA_psfile].str, ".ps"); + + if (global.multi_file) + fh = 0; + else { + const char *fn = global.filename; + fh = psopen(hl, fn, "toc"); + if (!fh) { + perror(fn); + goto error; + } + } + + ps_hid_export_to_file(hl, fh, options, &xform, appspec); + + global.multi_file = 0; + if (fh) { + rnd_ps_end_file(&global.ps); + fclose(fh); + } + + error:; +} + +static int ps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, ps_attribute_list, NUM_OPTIONS, ps_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int ps_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + rnd_design_t *hl = &camv.hidlib; + gds_t tmp_ln; + const char *name; + int newpage; + + gds_init(&tmp_ln); + TODO("project: needed for project multisheet export"); + name = "TODO:layer_name"; + + if (rnd_ps_printed_toc(&global.ps, group, name)) { + gds_uninit(&tmp_ln); + return 0; + } + + newpage = rnd_ps_is_new_page(&global.ps, group); + if (newpage) { + if ((global.ps.pagecount != 0) && global.had_page) { + rnd_fprintf(global.ps.outf, "showpage\n"); + } + if (global.multi_file) { + int nr; + const char *fn; + gds_t tmp; + + gds_init(&tmp); + fn = "TODO_ps_filename1"; + nr = rnd_ps_new_file(&global.ps, psopen(hl, global.filename, fn), fn); + gds_uninit(&tmp); + if (nr != 0) + return 0; + + rnd_ps_start_file(&global.ps, "sch-rnd release: sch-rnd " CAMV_VERS); + } + else + global.had_page = 1; + + + { + gds_t tmp = {0}; + const char *layer_fn = "TODO_ps_filename2"; + rnd_ps_page_frame(&global.ps, 1, layer_fn, 0); + gds_uninit(&tmp); + } + + rnd_ps_page_background(&global.ps, 0, 0, 1); + } + + gds_uninit(&tmp_ln); + return 1; +} + +static void ps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_ps_set_drawing_mode(&global.ps, hid, op, direct, screen); +} + +static rnd_color_t ps_last_color; +static void ps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + ps_last_color = *color; + rnd_ps_set_color(&global.ps, gc, color); +} + +static void ps_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_draw_rect(&global.ps, gc, x1, y1, x2, y2); +} + +static void ps_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_draw_line(&global.ps, gc, x1, y1, x2, y2); +} + +static void ps_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_ps_draw_arc(&global.ps, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void ps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_ps_fill_circle(&global.ps, gc, cx, cy, radius); +} + +static void ps_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + /* maybe tweak fill color so that light fills remain light grey */ + if (!global.ps.incolor) { + double intens2 = ps_last_color.fr * ps_last_color.fr + ps_last_color.fg * ps_last_color.fg + ps_last_color.fb * ps_last_color.fb; + + if (intens2 >= global.fill_gray_thrs) { + rnd_color_t clr = ps_last_color; + int avg = rnd_round((double)(clr.r + clr.g + clr.b) / 3.0); + clr.r = clr.g = clr.b = avg; + + global.ps.incolor = 1; + rnd_ps_set_color(&global.ps, gc, &clr); + global.ps.incolor = 0; + } + } + + rnd_ps_fill_polygon_offs(&global.ps, gc, n_coords, x, y, dx, dy); +} + + +static void ps_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + ps_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void ps_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_ps_fill_rect(&global.ps, gc, x1, y1, x2, y2); +} + + +rnd_hid_t ps_hid; + + +static int ps_inited = 0; +void ps_ps_init(rnd_hid_t * hid) +{ + if (ps_inited) + return; + + hid->get_export_options = ps_get_export_options; + hid->do_export = ps_do_export; + hid->parse_arguments = ps_parse_arguments; + hid->set_layer_group = ps_set_layer_group; + hid->make_gc = rnd_ps_make_gc; + hid->destroy_gc = rnd_ps_destroy_gc; + hid->set_drawing_mode = ps_set_drawing_mode; + hid->set_color = ps_set_color; + hid->set_line_cap = rnd_ps_set_line_cap; + hid->set_line_width = rnd_ps_set_line_width; + hid->set_draw_xor = rnd_ps_set_draw_xor; + hid->draw_line = ps_draw_line; + hid->draw_arc = ps_draw_arc; + hid->draw_rect = ps_draw_rect; + hid->fill_circle = ps_fill_circle; + hid->fill_polygon_offs = ps_fill_polygon_offs; + hid->fill_polygon = ps_fill_polygon; + hid->fill_rect = ps_fill_rect; + hid->set_crosshair = rnd_ps_set_crosshair; + + ps_inited = 1; +} + +static int ps_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nps exporter command line arguments:\n\n"); + rnd_hid_usage(ps_attribute_list, sizeof(ps_attribute_list) / sizeof(ps_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x ps [ps options] foo.rs\n\n"); + return 0; +} + +static void plugin_ps_uninit(void) +{ + rnd_remove_actions_by_cookie(ps_cookie); + rnd_export_remove_opts_by_cookie(ps_cookie); + ps_inited = 0; +} + +void hid_ps_uninit() +{ + plugin_ps_uninit(); + rnd_hid_remove_hid(&ps_hid); +} + +void hid_ps_init() +{ + memset(&ps_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&ps_hid); + ps_ps_init(&ps_hid); + + ps_hid.struct_size = sizeof(rnd_hid_t); + ps_hid.name = "ps"; + ps_hid.description = "Postscript export"; + ps_hid.exporter = 1; + ps_hid.mask_invert = 1; + ps_hid.argument_array = global.ps_values; + + ps_hid.usage = ps_usage; + + rnd_hid_register_hid(&ps_hid); + rnd_hid_load_defaults(&ps_hid, ps_attribute_list, NUM_OPTIONS); +} Index: tags/1.1.4/src_plugins/export_svg/Makefile =================================================================== --- tags/1.1.4/src_plugins/export_svg/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/export_svg/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make mod_export_svg Index: tags/1.1.4/src_plugins/export_svg/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/export_svg/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/export_svg/Plug.tmpasm (revision 818) @@ -0,0 +1,10 @@ +put /local/rnd/mod {export_svg} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/export_svg/export_svg.o +@] + +switch /local/module/export_svg/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/export_svg/export_svg.c =================================================================== --- tags/1.1.4/src_plugins/export_svg/export_svg.c (nonexistent) +++ tags/1.1.4/src_plugins/export_svg/export_svg.c (revision 818) @@ -0,0 +1,282 @@ +/* + * COPYRIGHT + * + * cschem - modular/flexible schematics editor - svg export + * Copyright (C) 2022 Tibor 'Igor2' Palinkas + * + * (Supported by NLnet NGI0 PET Fund in 2022) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/sch-rnd + * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html + * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "export.h" +#include "draw.h" +#include "data.h" + +static rnd_hid_t svg_hid; + +const char *svg_cookie = "export_svg"; + +static rnd_svg_t pctx_, *pctx = &pctx_; + +static const rnd_export_opt_t svg_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_svgfile 0 + + {"opacity", "Layer opacity", + RND_HATT_INTEGER, 0, 100, {100, 0, 0}, 0}, +#define HA_opacity 1 + + {"screen-colors", "Allow object highlight and selection color", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_screen_color 2 + + {"true-size", "Attempt to preserve true size for printing", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0}, +#define HA_true_size 3 + + {"layers", "List of layers to export or \"GUI\" for exporting what's visible on the GUI at the moment or empty for default export layer visibility", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0}, +#define HA_layers 4 +}; + +#define NUM_OPTIONS (sizeof(svg_attribute_list)/sizeof(svg_attribute_list[0])) + +static rnd_hid_attr_val_t svg_values[NUM_OPTIONS]; + +static char *out_filename; + +static const rnd_export_opt_t *svg_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec) +{ + if (n) + *n = NUM_OPTIONS; + return svg_attribute_list; +} + +void svg_hid_export_to_file(rnd_design_t *dsg, FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + rnd_design_t *hl = dsg; + rnd_hid_expose_ctx_t ctx; + + ctx.design = hl; + ctx.view.X1 = hl->dwg.X1; + ctx.view.Y1 = hl->dwg.Y1; + ctx.view.X2 = hl->dwg.X2; + ctx.view.Y2 = hl->dwg.Y2; + + pctx->outf = the_file; + + TODO("set flip if needed"); + rnd_svg_background(pctx); + + rnd_app.expose_main(&svg_hid, &ctx, xform); +} + +static void svg_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec) +{ + rnd_design_t *hl = design; + rnd_xform_t xform = {0}; + FILE *f = NULL; + + pctx->comp_cnt = 0; + + if (!options) { + svg_get_export_options(hid, 0, design, appspec); + options = svg_values; + } + + out_filename = camv_export_filename(hl, options[HA_svgfile].str, ".svg"); + + f = rnd_fopen_askovr(hl, out_filename, "wb", NULL); + if (f == NULL) { + int ern = errno; + rnd_message(RND_MSG_ERROR, "svg_do_export(): failed to open %s: %s\n", out_filename, strerror(ern)); + free(out_filename); + goto error; + } + free(out_filename); + + rnd_svg_init(pctx, hl, f, options[HA_opacity].lng, 1, options[HA_true_size].lng); + if (f != NULL) + rnd_svg_header(pctx); + + svg_hid_export_to_file(hl, pctx->outf, options, &xform); + + if (pctx->outf != NULL) { + rnd_svg_footer(pctx); + fclose(pctx->outf); + } + pctx->outf = NULL; + rnd_svg_uninit(pctx); + + error:; +} + +static int svg_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts2(hid, svg_attribute_list, sizeof(svg_attribute_list) / sizeof(svg_attribute_list[0]), svg_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int svg_set_layer_group(rnd_hid_t *hid, rnd_design_t *design, rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + if (is_empty) + return 0; + + { + gds_t tmp_ln; + const char *name; + + gds_init(&tmp_ln); + TODO("do we need this at all? there's no multi-page svg export"); + name = "TODO:layer_name"; + rnd_svg_layer_group_begin(pctx, group, name, 0); + gds_uninit(&tmp_ln); + } + return 1; +} + +static void svg_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + rnd_svg_set_drawing_mode(pctx, hid, op, direct, screen); +} + +static void svg_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + rnd_svg_set_color(pctx, gc, color); +} + +static void svg_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_draw_rect(pctx, gc, x1, y1, x2, y2); +} + +static void svg_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_fill_rect(pctx, gc, x1, y1, x2, y2); +} + +static void svg_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_svg_draw_line(pctx, gc, x1, y1, x2, y2); +} + +static void svg_draw_arc(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t width, rnd_coord_t height, rnd_angle_t start_angle, rnd_angle_t delta_angle) +{ + rnd_svg_draw_arc(pctx, gc, cx, cy, width, height, start_angle, delta_angle); +} + +static void svg_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_svg_fill_circle(pctx, gc, cx, cy, radius); +} + +static void svg_fill_polygon_offs(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_svg_fill_polygon_offs(pctx, gc, n_coords, x, y, dx, dy); +} + +static void svg_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_svg_fill_polygon_offs(pctx, gc, n_coords, x, y, 0, 0); +} + +static int svg_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nsvg exporter command line arguments:\n\n"); + rnd_hid_usage(svg_attribute_list, sizeof(svg_attribute_list) / sizeof(svg_attribute_list[0])); + fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x svg [svg options] foo.rs\n\n"); + return 0; +} + +int pplg_check_ver_export_svg(int ver_needed) { return 0; } + +void pplg_uninit_export_svg(void) +{ + rnd_export_remove_opts_by_cookie(svg_cookie); + rnd_hid_remove_hid(&svg_hid); +} + +int pplg_init_export_svg(void) +{ + RND_API_CHK_VER; + + memset(&svg_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&svg_hid); + + svg_hid.struct_size = sizeof(rnd_hid_t); + svg_hid.name = "svg"; + svg_hid.description = "Scalable Vector Graphics export"; + svg_hid.exporter = 1; + + svg_hid.get_export_options = svg_get_export_options; + svg_hid.do_export = svg_do_export; + svg_hid.parse_arguments = svg_parse_arguments; + svg_hid.set_layer_group = svg_set_layer_group; + svg_hid.make_gc = rnd_svg_make_gc; + svg_hid.destroy_gc = rnd_svg_destroy_gc; + svg_hid.set_drawing_mode = svg_set_drawing_mode; + svg_hid.set_color = svg_set_color; + svg_hid.set_line_cap = rnd_svg_set_line_cap; + svg_hid.set_line_width = rnd_svg_set_line_width; + svg_hid.set_draw_xor = rnd_svg_set_draw_xor; + svg_hid.draw_line = svg_draw_line; + svg_hid.draw_arc = svg_draw_arc; + svg_hid.draw_rect = svg_draw_rect; + svg_hid.fill_circle = svg_fill_circle; + svg_hid.fill_polygon = svg_fill_polygon; + svg_hid.fill_polygon_offs = svg_fill_polygon_offs; + svg_hid.fill_rect = svg_fill_rect; + svg_hid.set_crosshair = rnd_svg_set_crosshair; + svg_hid.argument_array = svg_values; + + svg_hid.usage = svg_usage; + + rnd_hid_register_hid(&svg_hid); + rnd_hid_load_defaults(&svg_hid, svg_attribute_list, NUM_OPTIONS); + + return 0; +} Index: tags/1.1.4/src_plugins/export_svg/export_svg.pup =================================================================== --- tags/1.1.4/src_plugins/export_svg/export_svg.pup (nonexistent) +++ tags/1.1.4/src_plugins/export_svg/export_svg.pup (revision 818) @@ -0,0 +1,10 @@ +$class export +$short export sheets to svg +$long Scalable Vector Graphics exporter +$state works +$fmt-native no +$fmt-feature-e svg +$package export-vector +dep lib_exp_text +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/gui/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/gui/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/gui/Plug.tmpasm (revision 818) @@ -0,0 +1,12 @@ +put /local/rnd/mod {gui} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/gui/camv_gui.o + $(PLUGDIR)/gui/layersel.o + $(PLUGDIR)/gui/status.o +@] + +switch /local/module/gui/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/gui/camv_gui.c =================================================================== --- tags/1.1.4/src_plugins/gui/camv_gui.c (nonexistent) +++ tags/1.1.4/src_plugins/gui/camv_gui.c (revision 818) @@ -0,0 +1,406 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2020 Tibor 'Igor2' Palinkas + * (copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include + +#include "event.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "data.h" +#include "plug_io_act.h" + +#include "layersel.h" +#include "status.h" +#include "draw.h" + +static const char *layersel_cookie = "camv_gui/layersel"; +static const char *status_cookie = "camv_gui/status"; +static const char *status_cookie2 = "camv_gui/status2"; +static const char *camv_gui_cookie = "camv_gui"; + +#define NOGUI() \ +do { \ + if ((rnd_gui == NULL) || (!rnd_gui->gui)) { \ + RND_ACT_IRES(1); \ + return 0; \ + } \ + RND_ACT_IRES(0); \ +} while(0) + +const char camv_acts_Popup[] = "Popup(MenuName, [obj-type])"; +const char camv_acth_Popup[] = "Bring up the popup menu specified by MenuName, optionally modified with the object type under the cursor.\n"; +fgw_error_t camv_act_Popup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char name[256], name2[256]; + const char *tn = NULL, *a0, *a1 = NULL; + int r = 1; + enum { + CTX_NONE, + CTX_OBJ_TYPE + } ctx_sens = CTX_NONE; + + NOGUI(); + + if (argc != 2 && argc != 3) + RND_ACT_FAIL(Popup); + + RND_ACT_CONVARG(1, FGW_STR, Popup, a0 = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, Popup, a1 = argv[2].val.str); + + *name = '\0'; + *name2 = '\0'; + + if (argc == 3) { + if (strcmp(a1, "obj-type") == 0) ctx_sens = CTX_OBJ_TYPE; + } + + if (strlen(a0) < sizeof(name) - 32) { + switch(ctx_sens) { + case CTX_OBJ_TYPE: + { + rnd_coord_t x, y; +/* pcb_objtype_t type; + void *o1, *o2, *o3;*/ + rnd_hid_get_coords("context sensitive popup: select object", &x, &y, 0); +#if 0 + type = pcb_search_screen(x, y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &o1, &o2, &o3); + if (type == 0) + type = pcb_search_screen(x, y, PCB_OBJ_CLASS_REAL, &o1, &o2, &o3); + + if (type == 0) + tn = "none"; + else + tn = pcb_obj_type_name(type); +#endif + sprintf(name, "/popups/%s-%s", a0, tn); + sprintf(name2, "/popups/%s-misc", a0); + } + break; + case CTX_NONE: + sprintf(name, "/popups/%s", a0); + break; + + } + } + + if (*name != '\0') + r = rnd_gui->open_popup(rnd_gui, name); + if ((r != 0) && (*name2 != '\0')) + r = rnd_gui->open_popup(rnd_gui, name2); + + RND_ACT_IRES(r); + return 0; +} + +static char *dup_cwd(void) +{ + char tmp[RND_PATH_MAX + 1]; + return rnd_strdup(rnd_get_wd(tmp)); +} + +static const char camv_acts_Load[] = "Load()\n" "Load(Project|Layer)"; +static const char camv_acth_Load[] = "Load a camv project or a layer from a user-selected file."; +static fgw_error_t camv_act_Load(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static char *last_project = NULL, *last_layer = NULL; + const char *function = "Layer"; + char *name = NULL; + int multisel = 0; + + if (last_layer == NULL) last_layer = dup_cwd(); + if (last_project == NULL) last_project = dup_cwd(); + + /* Called with both function and file name -> no gui */ + if (argc > 2) + return RND_ACT_CALL_C(RND_ACT_DESIGN, camv_act_LoadFrom, res, argc, argv); + + RND_ACT_MAY_CONVARG(1, FGW_STR, Load, function = argv[1].val.str); + + if (rnd_strcasecmp(function, "Layer") == 0) { + name = rnd_hid_fileselect(rnd_gui, "Load layer", "Import a layer from file", last_layer, NULL, NULL, "layer", RND_HID_FSD_READ | RND_HID_FSD_MULTI, NULL); + multisel = 1; + } + else if (rnd_strcasecmp(function, "Project") == 0) { + name = rnd_hid_fileselect(rnd_gui, "Load a project file", "load project (all layers) from file", last_project, ".lht", NULL, "project", RND_HID_FSD_READ, NULL); + multisel = 0; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid subcommand for Load(): '%s'\n", function); + RND_ACT_IRES(1); + return 0; + } + + if (name != NULL) { + if (multisel) { + char *n; + for(n = name; *n != '\0'; n += strlen(n)+1) { + if (rnd_conf.rc.verbose) + fprintf(stderr, "Load: Calling LoadFrom(%s, %s)\n", function, n); + rnd_actionl("LoadFrom", function, n, NULL); + } + } + else { + if (rnd_conf.rc.verbose) + fprintf(stderr, "Load: Calling LoadFrom(%s, %s)\n", function, name); + rnd_actionl("LoadFrom", function, name, NULL); + } + free(name); + } + + RND_ACT_IRES(0); + return 0; +} + +static int save_as(rnd_design_t *hl, int what, int as, const char *name) +{ + camv_design_t *camv = (camv_design_t *)hl; + const char *prev_fn, *whats, *prev_loadfn; + char *free_me = NULL; + int need_fsd, save_res = -1; + + if (name == NULL) { + prev_fn = camv->hidlib.fullpath; + if (prev_fn == NULL) + prev_fn = free_me = dup_cwd(); + prev_loadfn = camv->hidlib.loadname; + if (prev_loadfn == NULL) + prev_loadfn = prev_fn; + need_fsd = 1; + } + else { + prev_fn = name; + need_fsd = 0; + } + + /* invoke FSD if needed */ + switch(what) { + case 'd': /* design */ + if (need_fsd) + name = rnd_hid_fileselect(rnd_gui, "Save design", "Save all layers to a design file", prev_loadfn, ".tdx", NULL, "design", 0, NULL); + whats = "design"; + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first argument for Save() or SaveAs()\n"); + goto error; + } + + if (name != NULL) { /* NULL means cancel */ + if (rnd_conf.rc.verbose) + fprintf(stderr, "Save: Calling SaveTo(%s, %s)\n", whats, name); + save_res = rnd_actionva(hl, "SaveTo", whats, name, NULL); + } + else if (rnd_conf.rc.verbose) + fprintf(stderr, "Save: SaveTo(%s, ...) cancelled\n", whats); + + free(free_me); + return save_res; + + error:; + free(free_me); + return 1; +} + +static const char camv_acts_Save[] = "Save()\n" "Save(design)"; +static const char camv_acth_Save[] = "Save all sheets of a design to file."; +static const char camv_acts_SaveAs[] = "SaveAs(design, [filename])"; +static const char camv_acth_SaveAs[] = "Save all sheets of a design to file."; +static fgw_error_t camv_act_Save(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_design_t *hl = RND_ACT_DESIGN; + const char *actname = argv[0].val.func->name; + int as = (actname[4] == 'a') || (actname[4] == 'A'); + int what = 'd'; + const char *name = NULL; + + if (as) { + RND_ACT_MAY_CONVARG(1, FGW_STR, SaveAs, what = tolower(argv[1].val.cstr[0])); + RND_ACT_MAY_CONVARG(2, FGW_STR, SaveAs, name = argv[2].val.cstr); + } + else + RND_ACT_MAY_CONVARG(1, FGW_STR, Save, what = tolower(argv[1].val.cstr[0])); + + RND_ACT_IRES(save_as(hl, what, as, name)); + return 0; +} + +const char camv_acts_SwapSides[] = "SwapSides(-|v|h|r, [S])"; +const char camv_acth_SwapSides[] = "Swaps the side of the board you're looking at."; +fgw_error_t camv_act_SwapSides(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + camv_design_t *camv = (camv_design_t *)RND_ACT_DESIGN; + rnd_box_t vb; + rnd_coord_t x, y; + double xcent, ycent, xoffs, yoffs; + + RND_GUI_NOGUI(); + + rnd_hid_get_coords("Click to center of flip", &x, &y, 0); + + x = camv->crosshair_x; + y = camv->crosshair_y; + + rnd_gui->view_get(rnd_gui, &vb); + xcent = (double)(vb.X1 + vb.X2)/2.0; + ycent = (double)(vb.Y1 + vb.Y2)/2.0; + xoffs = xcent - x; + yoffs = ycent - y; + + camv_draw_inhibit_inc(); + if (argc > 1) { + const char *a, *b = ""; + + RND_ACT_CONVARG(1, FGW_STR, SwapSides, a = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, SwapSides, b = argv[2].val.str); + switch (a[0]) { + case '-': break; + case 'h': case 'H': + rnd_conf_toggle_heditor_("view/flip_x", view.flip_x); + xoffs = 0; + break; + case 'v': case 'V': + if (!rnd_conf.editor.view.flip_y) + yoffs = -yoffs; + else + yoffs = 0; + rnd_conf_toggle_heditor_("view/flip_y", view.flip_y); + break; + case 'r': case 'R': + xoffs = 0; + if (!rnd_conf.editor.view.flip_y) + yoffs = -yoffs; + else + yoffs = 0; + + rnd_conf_toggle_heditor_("view/flip_x", view.flip_x); + rnd_conf_toggle_heditor_("view/flip_y", view.flip_y); + break; + + default: + camv_draw_inhibit_dec(); + RND_ACT_IRES(1); + return 0; + } + + switch (b[0]) { + case 'S': + case 's': + camv_data_reverse_layers(camv, 0); + break; + } + } + + camv_draw_inhibit_dec(); + + rnd_gui->pan(rnd_gui, rnd_round(x + xoffs), rnd_round(y + yoffs), 0); + rnd_gui->set_crosshair(rnd_gui, x, y, RND_SC_PAN_VIEWPORT); + + rnd_gui->invalidate_all(rnd_gui); + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t camv_gui_action_list[] = { + {"PrintGUI", rnd_act_PrintDialog, rnd_acth_PrintDialog, rnd_acts_PrintDialog}, + {"Popup", camv_act_Popup, camv_acth_Popup, camv_acts_Popup}, + {"Load", camv_act_Load, camv_acth_Load, camv_acts_Load}, + {"Export", rnd_act_Export, rnd_acth_Export, rnd_acts_Export}, + {"Layer", camv_act_Layer, camv_acth_Layer, camv_acts_Layer}, + {"StatusSetText", camv_act_StatusSetText, camv_acth_StatusSetText, camv_acts_StatusSetText}, + {"Save", camv_act_Save, camv_acth_Save, camv_acts_Save}, + {"SaveAs", camv_act_Save, camv_acth_SaveAs, camv_acts_SaveAs}, + {"SwapSides", camv_act_SwapSides, camv_acth_SwapSides, camv_acts_SwapSides} +}; + +int pplg_check_ver_gui(int ver_needed) { return 0; } + +void pplg_uninit_gui(void) +{ + rnd_actionl("rnd_toolbar_uninit", NULL); + rnd_event_unbind_allcookie(status_cookie); + rnd_event_unbind_allcookie(layersel_cookie); + rnd_conf_hid_unreg(status_cookie); + rnd_conf_hid_unreg(status_cookie2); + rnd_remove_actions_by_cookie(camv_gui_cookie); +} + +static rnd_conf_hid_id_t install_events(const char *cookie, const char *paths[], rnd_conf_hid_callbacks_t cb[], void (*update_cb)(rnd_conf_native_t*,int,void*)) +{ + const char **rp; + rnd_conf_native_t *nat; + int n; + rnd_conf_hid_id_t conf_id; + + conf_id = rnd_conf_hid_reg(cookie, NULL); + for(rp = paths, n = 0; *rp != NULL; rp++, n++) { + memset(&cb[n], 0, sizeof(cb[0])); + cb[n].val_change_post = update_cb; + nat = rnd_conf_get_field(*rp); + if (nat != NULL) + rnd_conf_hid_set_cb(nat, conf_id, &cb[n]); + } + + return conf_id; +} + +int pplg_init_gui(void) +{ + const char *stpaths[] = { "editor/grid_unit", "editor/grid", "editor/view/flip_x", "editor/view/flip_y", NULL }; + const char *rdpaths[] = { "editor/grid_unit", NULL }; + static rnd_conf_hid_callbacks_t stcb[sizeof(stpaths)/sizeof(stpaths[0])]; + static rnd_conf_hid_callbacks_t rdcb[sizeof(rdpaths)/sizeof(rdpaths[0])]; + + rnd_event_bind(RND_EVENT_GUI_INIT, camv_layersel_gui_init_ev, NULL, layersel_cookie); + rnd_event_bind(CAMV_EVENT_LAYERS_CHANGED, camv_layersel_layer_chg_ev, NULL, layersel_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, camv_status_gui_init_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_USER_INPUT_KEY, camv_status_st_update_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_CROSSHAIR_MOVE, camv_status_rd_update_ev, NULL, status_cookie); + + install_events(status_cookie, stpaths, stcb, camv_status_st_update_conf); + install_events(status_cookie2, rdpaths, rdcb, camv_status_rd_update_conf); + + RND_REGISTER_ACTIONS(camv_gui_action_list, camv_gui_cookie); + rnd_actionl("rnd_toolbar_init", NULL); + return 0; +} Index: tags/1.1.4/src_plugins/gui/gui.pup =================================================================== --- tags/1.1.4/src_plugins/gui/gui.pup (nonexistent) +++ tags/1.1.4/src_plugins/gui/gui.pup (revision 818) @@ -0,0 +1,7 @@ +$class gui +$short Graphical User Interface +$long camv-specific GUI elements +$package lib-gui +$state works +dep lib_hid_common +default buildin Index: tags/1.1.4/src_plugins/gui/layersel.c =================================================================== --- tags/1.1.4/src_plugins/gui/layersel.c (nonexistent) +++ tags/1.1.4/src_plugins/gui/layersel.c (revision 818) @@ -0,0 +1,734 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2020,2023 Tibor 'Igor2' Palinkas + * (copied from pcb-rnd by the author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include + +#include +#include +#include + +#include +#include "data.h" +#include "event.h" +#include + +#include "layersel.h" + +/* Enable this to make sublayers and layer indices visible */ +#if 0 +#define LAYERSEL_DEBUG +#endif + +static const char *xpm_up[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ++ ", +" +@@+ ", +" +@@@@+ ", +" +@@@@@@+ ", +"+@@@@@@@@+", +"++++@@++++", +" +@@+ ", +" +@@+ ", +" +@@+ ", +" ++++ ", +}; + +static const char *xpm_upmost[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +"++++++++++", +"+@@@@@@@@+", +"++++@@++++", +" +@@@@@@+ ", +"+@@@@@@@@+", +"++++@@++++", +" +@@+ ", +" +@@+ ", +" +@@+ ", +" ++++ ", +}; + +static const char *xpm_down[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ++++ ", +" +@@+ ", +" +@@+ ", +" +@@+ ", +"++++@@++++", +"+@@@@@@@@+", +" +@@@@@@+ ", +" +@@@@+ ", +" +@@+ ", +" ++ ", +}; + +static const char *xpm_downmost[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ++++ ", +" +@@+ ", +" +@@+ ", +" +@@+ ", +"++++@@++++", +"+@@@@@@@@+", +" +@@@@@@+ ", +"++++@@++++", +"+@@@@@@@@+", +"++++++++++", +}; + +static const char *xpm_add[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ++++ ", +" +@@+ ", +" +@@+ ", +"++++@@++++", +"+@@@@@@@@+", +"+@@@@@@@@+", +"++++@@++++", +" +@@+ ", +" +@@+ ", +" ++++ ", +}; + +static const char *xpm_del[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ", +" ", +" ", +"++++++++++", +"+@@@@@@@@+", +"+@@@@@@@@+", +"++++++++++", +" ", +" ", +" ", +}; + + +static const char *all_vis_xpm[] = { +"12 9 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ", +" ++++ ", +" ++@@@@++ ", +" +@@@++@@@+ ", +"+@@@++++@@@+", +" +@@@++@@@+ ", +" ++@@@@++ ", +" ++++ ", +" ", +}; + +static const char *all_invis_xpm[] = { +"12 9 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" @+@ ", +" @+@+++ ", +" +@+@@@++ ", +" +@@@+@@@@+ ", +"+@@@+@+@@@@+", +" +@@@+@+@@+ ", +" ++@@@@+@ ", +" ++++@+@ ", +" @+@", +}; + + +typedef struct { + char buf[32][20]; + const char *xpm[32]; +} gen_xpm_t; + +typedef struct layersel_ctx_s layersel_ctx_t; + +typedef struct { + int wvis_on, wvis_off, wlab; + int wunsel, wsel; + gen_xpm_t on, off; + rnd_cardinal_t lid; + layersel_ctx_t *ls; +} ls_layer_t; + + +struct layersel_ctx_s { + rnd_hid_dad_subdialog_t sub; + camv_design_t *camv; + int sub_inited; + int wbut_up, wbut_down, wbut_top, wbut_bottom, wbut_load, wbut_remove, wbut_vis, wbut_invis; + int lock_vis, lock_sel; + vtp0_t layers; /* -> ls_layer_t */ +}; + +static layersel_ctx_t layersel; + +static void lys_update_vis(camv_design_t *camv, ls_layer_t *lys) +{ + camv_layer_t **ly; + int hide_on = 1, hide_off = 1; + + if (lys == NULL) + return; + + ly = (camv_layer_t **)vtp0_get(&camv->layers, lys->lid, 0); + if ((ly != NULL) && (*ly != NULL)) { + hide_on = !(*ly)->vis; + hide_off = !!(*ly)->vis; + } + + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_on, hide_on); + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_off, hide_off); +} + +static void layer_vis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_layer_t *lys = attr->user_data; + camv_design_t *camv = lys->ls->camv; + camv_layer_t **ly = (camv_layer_t **)vtp0_get(&camv->layers, lys->lid, 0); + + if ((ly == NULL) || (*ly == NULL)) + return; + + lys->ls->lock_vis++; + camv_layer_set_vis(camv, lys->lid, !(*ly)->vis, 1); + lys->ls->lock_vis--; + + lys_update_vis(camv, lys); + camv_hid_redraw(camv); +} + +static void layer_unselect(layersel_ctx_t *ls) +{ + ls_layer_t **lys; + if (ls->camv->lysel < 0) + return; + + lys = (ls_layer_t **)vtp0_get(&ls->layers, ls->camv->lysel, 0); + if ((lys != NULL) && (*lys != NULL)) + rnd_gui->attr_dlg_widget_state(ls->sub.dlg_hid_ctx, (*lys)->wlab, 1); + + camv_layer_select(ls->camv, -1); +} + +static void layer_select_idx(layersel_ctx_t *ls, int idx) +{ + ls_layer_t **lys; + layer_unselect(ls); + lys = (ls_layer_t **)vtp0_get(&ls->layers, idx, 0); + if (lys != NULL) + rnd_gui->attr_dlg_widget_state(ls->sub.dlg_hid_ctx, (*lys)->wlab, 2); + else + idx = -1; + camv_layer_select(layersel.camv, idx); +} + +static void layer_select(ls_layer_t *lys) +{ + layer_select_idx(lys->ls, lys->lid); +} + + +static void layer_sel_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + layer_select((ls_layer_t *)attr->user_data); +} + + +static void layer_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + layer_select((ls_layer_t *)attr->user_data); + rnd_actionl("Popup", "layer", NULL); +} + +static void layer_button_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + layersel_ctx_t *ls = attr->user_data; + int wid = attr - ls->sub.dlg; + if (wid == ls->wbut_up) rnd_actionl("Layer", "up", NULL); + else if (wid == ls->wbut_down) rnd_actionl("Layer", "down", NULL); + else if (wid == ls->wbut_top) rnd_actionl("Layer", "top", NULL); + else if (wid == ls->wbut_bottom) rnd_actionl("Layer", "bottom", NULL); + else if (wid == ls->wbut_load) { rnd_actionl("Load", "Layer", NULL) || rnd_actionva(&camv.hidlib, "Zoom", "auto_first", NULL); } + else if (wid == ls->wbut_remove) rnd_actionl("Layer", "del", NULL); + else if (wid == ls->wbut_vis) rnd_actionl("Layer", "all-visible", NULL); + else if (wid == ls->wbut_invis) rnd_actionl("Layer", "all-invisible", NULL); + else rnd_message(RND_MSG_ERROR, "Internal error: layer_button_cb(): invalid wid\n"); +} + +/* draw a visibility box: filled or partially filled with layer color */ +static void layer_vis_box(gen_xpm_t *dst, int filled, const rnd_color_t *color, int brd, int hatch, int width, int height, int slant) +{ + int max_height = height; + char *p; + unsigned int w, line = 0, n; + + rnd_snprintf(dst->buf[line++], 20, "%d %d 4 1", width, height); + strcpy(dst->buf[line++], ". c None"); + strcpy(dst->buf[line++], "u c None"); + strcpy(dst->buf[line++], "b c #000000"); + rnd_snprintf(dst->buf[line++], 20, "c c #%02X%02X%02X", color->r, color->g, color->b); + + while (height--) { + w = width; + p = dst->buf[line++]; + while (w--) { + if ((height < brd) || (height >= max_height-brd) || (w < brd) || (w >= width-brd)) + *p = 'b'; /* frame */ + else if ((hatch) && (((w - height) % 4) == 0)) + *p = '.'; + else if ((width-w+slant < height) || (filled)) + *p = 'c'; /* layer color fill (full or up-left triangle) */ + else + *p = 'u'; /* the unfilled part when triangle should be transparent */ + p++; + } + *p = '\0'; + } + + for(n=0; n < line; n++) + dst->xpm[n] = dst->buf[n]; +} + +static void layersel_create_layer(layersel_ctx_t *ls, ls_layer_t *lys, int lidx, const char *short_name, const char *name, const rnd_color_t *color, int brd, int hatch) +{ + if (name == NULL) + name = ""; + + if (short_name == NULL) { + short_name = strrchr(name, '/'); + if (short_name == NULL) + short_name = name; + else + short_name++; + } + + layer_vis_box(&lys->on, 1, color, brd, hatch, 16, 16, 5); + layer_vis_box(&lys->off, 0, color, brd, hatch, 16, 16, 5); + + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_PICTURE(ls->sub.dlg, lys->on.xpm); + lys->wvis_on = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb); + RND_DAD_PICTURE(ls->sub.dlg, lys->off.xpm); + lys->wvis_off = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb); +#ifdef LAYERSEL_DEBUG + { + char idx[32]; + sprintf(idx, "{%d}", lidx); + RND_DAD_LABEL(ls->sub.dlg, idx); + } +#endif + RND_DAD_LABEL(ls->sub.dlg, short_name); + lys->wlab = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_sel_cb); + RND_DAD_RIGHT_CB(ls->sub.dlg, layer_right_cb); + RND_DAD_HELP(ls->sub.dlg, name); + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_docked_create(layersel_ctx_t *ls, camv_design_t *camv) +{ + long n, i; /* must be signed */ + + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + + /* build layers in reverse order (rendering needs to be fast so goes from front to back) */ + for(i = 0, n = camv->layers.used-1; n >= 0; n--) { + camv_layer_t *ly = camv->layers.array[n]; + ls_layer_t *lys, **lysp; + + lysp = (ls_layer_t **)vtp0_get(&ls->layers, n, 1); + +#ifndef LAYERSEL_DEBUG + if (ly->sub) { + if ((lysp != NULL) && (*lysp != NULL)) { + free(*lysp); + *lysp = NULL; + } + continue; + } +#endif + if (*lysp == NULL) + *lysp = calloc(sizeof(ls_layer_t), 1); + lys = *lysp; + lys->lid = n; + lys->ls = ls; + layersel_create_layer(ls, lys, n, ly->short_name, ly->name, &ly->color, 1, 0); + i++; + } + + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL); + RND_DAD_END(ls->sub.dlg); + + + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_up); + RND_DAD_HELP(ls->sub.dlg, "Move layer up in the stack"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_up = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_down); + RND_DAD_HELP(ls->sub.dlg, "Move layer down in the stack"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_down = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_upmost); + RND_DAD_HELP(ls->sub.dlg, "Move layer to the top of the stack"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_top = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_downmost); + RND_DAD_HELP(ls->sub.dlg, "Move layer to the bottom of the stack"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_bottom = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_add); + RND_DAD_HELP(ls->sub.dlg, "Add (load) a new layer"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_load = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, xpm_del); + RND_DAD_HELP(ls->sub.dlg, "Del (remove) a layer"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_remove = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, all_vis_xpm); + RND_DAD_HELP(ls->sub.dlg, "all layers visible"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_vis = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, all_invis_xpm); + RND_DAD_HELP(ls->sub.dlg, "all layers invisible\nexcept for the current layer group"); + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_button_cb); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, ls); + ls->wbut_invis = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL); + RND_DAD_END(ls->sub.dlg); + RND_DAD_END(ls->sub.dlg); + RND_DAD_END(ls->sub.dlg); + RND_DAD_DEFSIZE(ls->sub.dlg, 210, 200); + RND_DAD_MINSIZE(ls->sub.dlg, 100, 100); +} + +static void layersel_update_vis(layersel_ctx_t *ls, camv_design_t *camv) +{ + long n; + for(n = 0; n < ls->layers.used; n++) + lys_update_vis(camv, ls->layers.array[n]); +} + +static void layersel_build(void) +{ + layersel_docked_create(&layersel, &camv); + if (rnd_hid_dock_enter(&layersel.sub, RND_HID_DOCK_LEFT, "layersel") == 0) { + layersel.sub_inited = 1; + layersel_update_vis(&layersel, &camv); + } +} + +void camv_layersel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) { + layersel.camv = &camv; + layersel_build(); + } +} + +void camv_layersel_vis_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((!layersel.sub_inited) || (layersel.lock_vis > 0)) + return; + layersel_update_vis(&layersel, &camv); +} + +void camv_layersel_layer_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL) && (layersel.sub_inited)) { + rnd_hid_dock_leave(&layersel.sub); + layersel.sub_inited = 0; + layersel_build(); + } +} + +/* return whether the layer at idx is a sub-layer */ +static int is_sub(int idx) +{ + camv_design_t *camv = layersel.camv; + return ((camv_layer_t *)camv->layers.array[idx])->sub; +} + +/* low level move a layer from src to dst, in 'step' direction. Returns new dst. */ +static int layer_move_(int src, int dst, int step) +{ + int n; + camv_design_t *camv = layersel.camv; + camv_layer_t *dst_ly = camv->layers.array[src]; + + for(n = src; step > 0 ? (n < dst) : (n > dst); n += step) + camv->layers.array[n] = camv->layers.array[n+step]; + camv->layers.array[dst] = dst_ly; + + return dst - step; +} + +static void layer_move(int dst) +{ + int step, sn, snv, src = layersel.camv->lysel, dst_fin; + camv_design_t *camv = layersel.camv; + + step = dst > src ? 1 : -1; + + /* we may need to move multiple sublayers; determine how many */ + for(snv = src+1; (snv > 0) && (snv < camv->layers.used) && is_sub(snv); snv++); + +/*rnd_trace("dst1=%d step=%d snv=%d blocklen=%d\n", dst, step, snv, snv-src);*/ + + if (step > 0) { + if (snv-src > 1) + dst+=(snv-src-1); + if (dst >= camv->layers.used) + dst = camv->layers.used-1; + + /* move dst to jump over own sub-layers when moving up */ + if (((dst+1) < camv->layers.used) && is_sub(dst+1)) { + for(dst++; ((dst+1) < camv->layers.used) && is_sub(dst+1); dst++) ; + if (dst >= camv->layers.used) + return; + } + } + else { + /* move dst to jump over sub-layers of the target when moving down */ + for(; (dst > 0) && is_sub(dst); dst--) ; + } + +/*rnd_trace("dst2=%d\n", dst);*/ + + + if (step > 0) { + for(sn = snv-1; sn >= src; sn--) { +/*rnd_trace("move+ %d to %d\n", sn, dst);*/ + dst = layer_move_(sn, dst, step); + } + dst_fin = dst + step; + } + else { + dst_fin = dst; + for(sn = src; sn < snv; sn++) { +/*rnd_trace("move- %d to %d\n", sn, dst);*/ + dst = layer_move_(sn, dst, step); + } + } + + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + layer_select(layersel.layers.array[dst_fin]); + camv_hid_redraw(camv); +} + +static void layer_del(void) +{ + int src = layersel.camv->lysel; + camv_layer_t *ly = layersel.camv->layers.array[src]; + + vtp0_remove(&layersel.camv->layers, src, 1); + vtp0_remove(&layersel.layers, src, 1); + camv_layer_destroy(ly); + + camv_layer_select(layersel.camv, -1); + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + camv_hid_redraw(layersel.camv); +} + +static void layer_set_color(const rnd_color_t clr) +{ + int src = layersel.camv->lysel; + camv_layer_t *ly = layersel.camv->layers.array[src]; + + ly->color = clr; + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); +} + +static void layer_rename(const char *name) +{ + int src = layersel.camv->lysel; + camv_layer_t *ly = layersel.camv->layers.array[src]; + + free(ly->short_name); + ly->short_name = rnd_strdup(name); + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); +} + +static void layer_del_all(void) +{ + long n; + for(n = layersel.camv->layers.used-1; n >= 0; n--) { + camv_layer_t *ly = layersel.camv->layers.array[n]; + + vtp0_remove(&layersel.camv->layers, n, 1); + vtp0_remove(&layersel.layers, n, 1); + camv_layer_destroy(ly); + } + + camv_layer_select(layersel.camv, -1); + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + + camv_hid_redraw(layersel.camv); +} + +static void all_vis(camv_design_t *camv, int vis) +{ + long lid; + + for(lid = 0; lid < camv->layers.used; lid++) + camv_layer_set_vis(camv, lid, vis, 1); + + rnd_event(&layersel.camv->hidlib, CAMV_EVENT_LAYERS_CHANGED, NULL); + camv_hid_redraw(layersel.camv); +} + +/* DOC: layer.html */ +const char camv_acts_Layer[] = "Layer([up|down|top|bottom|del|getidx|getlen|setcolor|rename])"; +const char camv_acth_Layer[] = "Move or remove the current layer or return index\n"; +fgw_error_t camv_act_Layer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = NULL, *clrstr, *name; + camv_design_t *camv = layersel.camv; + + if ((argc != 2) && (argc != 3)) + RND_ACT_FAIL(Layer); + + RND_ACT_CONVARG(1, FGW_STR, Layer, cmd = argv[1].val.str); + + if (strcmp(cmd, "down") == 0) { + if (camv->lysel < 0) goto nolayer; + if (camv->lysel == 0) goto nop; + layer_move(camv->lysel-1); + } + else if (strcmp(cmd, "up") == 0) { + if (camv->lysel < 0) goto nolayer; + if (camv->lysel == camv->layers.used-1) goto nop; + layer_move(camv->lysel+1); + } + else if (strcmp(cmd, "bottom") == 0) { + if (camv->lysel < 0) goto nolayer; + if (camv->lysel == 0) goto nop; + layer_move(0); + } + else if (strcmp(cmd, "top") == 0) { + if (camv->lysel < 0) goto nolayer; + if (camv->lysel == camv->layers.used-1) goto nop; + layer_move(camv->layers.used-1); + } + else if (strcmp(cmd, "del") == 0) { + if (camv->lysel < 0) goto nolayer; + layer_del(); + } + else if (strcmp(cmd, "all-visible") == 0) { + all_vis(camv, 1); + } + else if (strcmp(cmd, "all-invisible") == 0) { + all_vis(camv, 0); + } + else if (rnd_strcasecmp(cmd, "delall") == 0) { + if (camv->lysel < 0) goto nolayer; + layer_del_all(); + } + else if (rnd_strcasecmp(cmd, "getidx") == 0) { + RND_ACT_IRES(camv->lysel); + return 0; + } + else if (rnd_strcasecmp(cmd, "select") == 0) { + int idx; + RND_ACT_CONVARG(2, FGW_INT, Layer, idx = argv[2].val.nat_int); + layer_select_idx(&layersel, idx); + return 0; + } + else if (rnd_strcasecmp(cmd, "getlen") == 0) { + RND_ACT_IRES(camv->layers.used); + return 0; + } + else if (rnd_strcasecmp(cmd, "setcolor") == 0) { + rnd_color_t clr; + + RND_ACT_CONVARG(2, FGW_STR, Layer, clrstr = argv[2].val.str); + if (rnd_color_load_str(&clr, clrstr) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid color in Layer(setcolor): '%s'\b", clrstr); + RND_ACT_IRES(-1); + return 0; + } + + layer_set_color(clr); + } + else if (rnd_strcasecmp(cmd, "rename") == 0) { + RND_ACT_CONVARG(2, FGW_STR, Layer, name = argv[2].val.str); + layer_rename(name); + } + + else { + RND_ACT_FAIL(Layer); + } + + nop:; + RND_ACT_IRES(0); + return 0; + + nolayer:; + rnd_message(RND_MSG_ERROR, "no layer selected"); + RND_ACT_IRES(-1); + return 0; +} Index: tags/1.1.4/src_plugins/gui/layersel.h =================================================================== --- tags/1.1.4/src_plugins/gui/layersel.h (nonexistent) +++ tags/1.1.4/src_plugins/gui/layersel.h (revision 818) @@ -0,0 +1,8 @@ +void camv_layersel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void camv_layersel_vis_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void camv_layersel_layer_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + + +extern const char camv_acts_Layer[]; +extern const char camv_acth_Layer[]; +fgw_error_t camv_act_Layer(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/1.1.4/src_plugins/gui/status.c =================================================================== --- tags/1.1.4/src_plugins/gui/status.c (nonexistent) +++ tags/1.1.4/src_plugins/gui/status.c (revision 818) @@ -0,0 +1,301 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (based on pcb-rnd by the same author) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include "data.h" +#include "conf_core.h" +#include "crosshair.h" + +#include "status.h" + +#define COMPACT 1 + + +typedef struct { + rnd_hid_dad_subdialog_t stsub, rdsub; /* st is for the bottom status line, rd is for the top readouts */ + int stsub_inited, rdsub_inited; + int wst1, wsttxt; + int st_has_text; + int wrdunit, wrd2[2]; + gds_t buf; /* save on allocation */ + int lock; + const rnd_unit_t *last_unit; +} status_ctx_t; + +static status_ctx_t status; + +static void build_st_line1(void) +{ + char kbd[128]; + rnd_hid_cfg_keys_t *kst = rnd_gui->key_state; + + if (kst != NULL) { + if (kst->seq_len_action > 0) { + int len; + memcpy(kbd, "(last: ", 7); + len = rnd_hid_cfg_keys_seq(kst, kbd+7, sizeof(kbd)-9); + memcpy(kbd+len+7, ")", 2); + } + else + rnd_hid_cfg_keys_seq(kst, kbd, sizeof(kbd)); + } + else + *kbd = '\0'; + + + rnd_append_printf(&status.buf, + "%m+ " + "grid=%$mS " + "kbd=%s view: %s", + rnd_conf.editor.grid_unit->allow, + camv.hidlib.grid, + kbd, ((rnd_conf.editor.view.flip_x ^ rnd_conf.editor.view.flip_y) ? "top" : "bottom")); +} + +static void build_st_help(void) +{ + static const rnd_unit_t *unit_mm = NULL, *unit_mil; + const rnd_unit_t *unit_inv; + + if (unit_mm == NULL) { /* cache mm and mil units to save on the lookups */ + unit_mm = rnd_get_unit_struct("mm"); + unit_mil = rnd_get_unit_struct("mil"); + } + if (rnd_conf.editor.grid_unit == unit_mm) + unit_inv = unit_mil; + else + unit_inv = unit_mm; + + rnd_append_printf(&status.buf, + "%m+" + "grid=%$mS\n" + "looking from the %s", + unit_inv->allow, + camv.hidlib.grid, + ((rnd_conf.editor.view.flip_x ^ rnd_conf.editor.view.flip_y) ? "top" : "bottom") + ); +} + + +static void status_st_view2dlg(void) +{ + static rnd_hid_attr_val_t hv; + + if (!status.stsub_inited) + return; + + status.buf.used = 0; + build_st_line1(); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wst1, &hv); + + status.buf.used = 0; + build_st_help(); + rnd_gui->attr_dlg_set_help(status.stsub.dlg_hid_ctx, status.wst1, status.buf.array); +} + +static void status_rd_view2dlg(void) +{ + static rnd_hid_attr_val_t hv; + + if ((status.lock) || (!status.rdsub_inited)) + return; + + /* coordinate readout (right side box) */ + if (COMPACT) { + status.buf.used = 0; + rnd_append_printf(&status.buf, "%m+%-mS", rnd_conf.editor.grid_unit->allow, camv.crosshair_x); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd2[0], &hv); + + status.buf.used = 0; + rnd_append_printf(&status.buf, "%m+%-mS", rnd_conf.editor.grid_unit->allow, camv.crosshair_y); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd2[1], &hv); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd2[1], 0); + } + else { + status.buf.used = 0; + rnd_append_printf(&status.buf, "%m+%-mS %-mS", rnd_conf.editor.grid_unit->allow, camv.crosshair_x, camv.crosshair_y); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd2[0], &hv); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd2[1], 1); + } + + if (status.last_unit != rnd_conf.editor.grid_unit) { + status.lock++; + status.last_unit = rnd_conf.editor.grid_unit; + hv.str = rnd_conf.editor.grid_unit->suffix; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrdunit, &hv); + status.lock--; + } +} + +static void unit_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + if (rnd_conf.editor.grid_unit == rnd_get_unit_struct("mm")) + rnd_actionva(&camv.hidlib, "SetUnits", "mil", NULL); + else + rnd_actionva(&camv.hidlib, "SetUnits", "mm", NULL); + + status_rd_view2dlg(); +} + +static void status_docked_create_st() +{ + RND_DAD_BEGIN_VBOX(status.stsub.dlg); + RND_DAD_COMPFLAG(status.stsub.dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_LABEL(status.stsub.dlg, ""); + RND_DAD_COMPFLAG(status.stsub.dlg, RND_HATF_HIDE); + status.wsttxt = RND_DAD_CURRENT(status.stsub.dlg); + RND_DAD_LABEL(status.stsub.dlg, ""); + status.wst1 = RND_DAD_CURRENT(status.stsub.dlg); + RND_DAD_END(status.stsub.dlg); +} + +/* append an expand-vbox to eat up excess space for center-align */ +static void vpad(rnd_hid_dad_subdialog_t *sub) +{ + RND_DAD_BEGIN_VBOX(sub->dlg); + RND_DAD_COMPFLAG(sub->dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_END(sub->dlg); +} + +static void btn_support_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&camv.hidlib, "irc", NULL); +} + +static void status_docked_create_rd(rnd_design_t *hidlib) +{ + const char *xpm_ = "", **support_icon = &xpm_; + fgw_arg_t res, args[2]; + int n; + + /* fetch the xpm using the action API so the plugin doesn't start depending on GUI plugins */ + args[1].type = FGW_STR; + args[1].val.str = "online_help"; + if ((rnd_actionv_bin(hidlib, "rnd_dlg_xpm_by_name", &res, 2, args) == 0) && (res.type == FGW_PTR)) + support_icon = res.val.ptr_void; + + RND_DAD_BEGIN_HBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_TIGHT); + RND_DAD_PICBUTTON(status.rdsub.dlg, support_icon); + RND_DAD_CHANGE_CB(status.rdsub.dlg, btn_support_cb); + RND_DAD_BEGIN_VBOX(status.rdsub.dlg); + RND_DAD_COMPFLAG(status.rdsub.dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + vpad(&status.rdsub); + for(n = 0; n < 2; n++) { + RND_DAD_LABEL(status.rdsub.dlg, ""); + status.wrd2[n] = RND_DAD_CURRENT(status.rdsub.dlg); + } + vpad(&status.rdsub); + RND_DAD_END(status.rdsub.dlg); + RND_DAD_BUTTON(status.rdsub.dlg, ""); + status.wrdunit = RND_DAD_CURRENT(status.rdsub.dlg); + RND_DAD_CHANGE_CB(status.rdsub.dlg, unit_change_cb); + RND_DAD_END(status.rdsub.dlg); +} + + +void camv_status_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) { + status_docked_create_st(); + if (rnd_hid_dock_enter(&status.stsub, RND_HID_DOCK_BOTTOM, "status") == 0) { + status.stsub_inited = 1; + status_st_view2dlg(); + } + + status_docked_create_rd(hidlib); + if (rnd_hid_dock_enter(&status.rdsub, RND_HID_DOCK_TOP_RIGHT, "readout") == 0) { + status.rdsub_inited = 1; + status_rd_view2dlg(); + } + } +} + +void camv_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + status_st_view2dlg(); +} + +void camv_status_rd_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data) +{ + status_rd_view2dlg(); +} + +void camv_status_st_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_st_view2dlg(); +} + +void camv_status_rd_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_rd_view2dlg(); +} + +const char camv_acts_StatusSetText[] = "StatusSetText([text])\n"; +const char camv_acth_StatusSetText[] = "Replace status printout with text temporarily; turn status printout back on if text is not provided."; +fgw_error_t camv_act_StatusSetText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *text = NULL; + + if (argc > 2) + RND_ACT_FAIL(StatusSetText); + + RND_ACT_MAY_CONVARG(1, FGW_STR, StatusSetText, text = argv[1].val.str); + + if (text != NULL) { + rnd_hid_attr_val_t hv; + hv.str = text; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wsttxt, &hv); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst1, 1); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wsttxt, 0); + status.st_has_text = 1; + } + else { + status.st_has_text = 0; + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst1, 0); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wsttxt, 1); + status_st_view2dlg(); + } + + RND_ACT_IRES(0); + return 0; +} + Index: tags/1.1.4/src_plugins/gui/status.h =================================================================== --- tags/1.1.4/src_plugins/gui/status.h (nonexistent) +++ tags/1.1.4/src_plugins/gui/status.h (revision 818) @@ -0,0 +1,14 @@ +#include +#include +#include + +void camv_status_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void camv_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data); +void camv_status_rd_update_conf(rnd_conf_native_t *cfg, int arr_idx, void *user_data); +void camv_status_st_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void camv_status_rd_update_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + +extern const char camv_acts_StatusSetText[]; +extern const char camv_acth_StatusSetText[]; +fgw_error_t camv_act_StatusSetText(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: tags/1.1.4/src_plugins/import_excellon/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/import_excellon/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/import_excellon/Plug.tmpasm (revision 818) @@ -0,0 +1,10 @@ +put /local/rnd/mod {import_excellon} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/import_excellon/excellon.o +@] + +switch /local/module/import_excellon/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/import_excellon/excellon.c =================================================================== --- tags/1.1.4/src_plugins/import_excellon/excellon.c (nonexistent) +++ tags/1.1.4/src_plugins/import_excellon/excellon.c (revision 818) @@ -0,0 +1,555 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "data.h" +#include "plug_io.h" +#include "obj_any.h" + + +typedef struct { + /* static: set once in the header */ + vtc0_t tools; + int fmat; /* format version */ + double metric_scale; + unsigned int has_metric_scale:1; + unsigned int inch:1; + unsigned int inbody:1; + unsigned int started:1; /* M48 detected */ + unsigned int got_unit:1; + unsigned int leading_zero:1; + + /* dynamic */ + unsigned int rout:1; + unsigned int tool_down:1; + unsigned int eof:1; /* M30 */ + rnd_coord_t x, y; /* current pos */ + long tool; + camv_layer_t *ly; + + /* parser */ + long lineno; +} exc_t; + +static void exc_gen_line(exc_t *exc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + camv_any_obj_t *o = (camv_any_obj_t *)camv_line_new(); + o->line.x1 = x1; o->line.y1 = y1; + o->line.x2 = x2; o->line.y2 = y2; + o->line.thick = exc->tools.array[exc->tool]; + camv_obj_add_to_layer(exc->ly, o); +} + + +RND_INLINE rnd_coord_t exc2coord(exc_t *exc, double d) +{ + if (exc->inch) + return RND_MIL_TO_COORD(d*1000.0); + return RND_MM_TO_COORD(d); +} + +static double exc_strtod(exc_t *exc, const char *str, char **end) +{ + const char *s; + char tmp[32], *start, *o; + int len, has_dot = 0, neg = 0; + double res; + + /* copy digits and dots to start, which is in the middle of tmp so it + can be easily extended in both directions */ + start = o = tmp+16; + if (*str == '-') { + neg = 1; + str++; + } + for(s = str, len = 0; (isdigit(*s) || (*s == '.')); s++,len++) { + if (*s == '.') + has_dot = 1; + *o = *s; + o++; + if (len > 14) { + rnd_message(RND_MSG_ERROR, "excellon: invalid coord '%s' (too long)\n", str); + return 0; + } + } + *end = (char *)s; + *o = '\0'; + + /* make sure we have exactly 6 digits */ + if (len < 6) { + if (exc->leading_zero) { + while(len < 6) { + *o = '0'; + o++; + len++; + } + *o = '\0'; + } + else { + while(len < 6) { + start--; + *start = '0'; + len++; + } + } + } + else if (len > 6) + start[6] = '\0'; + + + res = strtod(start, NULL); + if (neg) + res = -res; + +/* printf("CNC C: '%s' -> '%s' -> %f end='%s'\n", str, start, res, *end);*/ + + if (exc->inch && !has_dot) { + /* old INCH format with no decimal point: 00.0000 format */ + res /= 10000.0; + } + else if (!exc->inch && exc->has_metric_scale && !has_dot) { + /* METRIC,00.000 flexible format */ + res /= exc->metric_scale; + } + return res; +} + +static int exc_load_tool(exc_t *exc, char **line, long idx) +{ + char *end; + rnd_coord_t *td; + double d = strtod(*line, &end); + + if ((*end != '\0') && (*end != 'F') && (*end != 'S')) { /* F is maybe feed rate, S is maybe spindle rpm */ + rnd_message(RND_MSG_ERROR, "excellon: invalid tool diameter '%s'\n", *line); + return -1; + } + *line = end; + td = vtc0_get(&exc->tools, idx, 1); + if (td == NULL) { + rnd_message(RND_MSG_ERROR, "excellon: failed to allocate tool id %ld\n", idx); + return -1; + } + *td = exc2coord(exc, d); + return 0; +} + +static void expect_fmat(exc_t *exc, int fmat) +{ + if (exc->fmat == 0) return; + if (exc->fmat != fmat) + rnd_message(RND_MSG_ERROR, "excellon: WARNING: unexpected command for format in line %ld; format expected is %d, but file says it's %d \n", exc->lineno, fmat, exc->fmat); +} + +static int exc_parse_header(exc_t *exc, char **line) +{ + if ((*line)[0] == '%') { + (*line)++; + exc->inbody = 1; + return 0; + } + + if (strncmp(*line, "FMAT,", 5) == 0) { + char *end; + + exc->fmat = strtol((*line)+5, &end, 10); + *line = end; + if (!isspace(*end) && (*end != '\0')) { + rnd_message(RND_MSG_ERROR, "excellon: invalid format version: %s\n", *line); + return -1; + } + if ((exc->fmat < 0) || (exc->fmat > 2)) { + rnd_message(RND_MSG_ERROR, "excellon: unknown format version: %s; please make a bugreport with this file\n", *line); + return -1; + } + return 0; + } + + if (strcmp(*line, "M95") == 0) { + (*line) += 3; + exc->inbody = 1; + return 0; + } + + if (strcmp(*line, "M48") == 0) { + (*line) += 3; + exc->started = 1; + return 0; + } + + if ((strcmp(*line, "M30") == 0) || (strcmp(*line, "M00") == 0) || (strcmp(*line, "M02") == 0)) { + if ((*line)[2] == '2') expect_fmat(exc, 1); + if ((*line)[2] == '0') expect_fmat(exc, 2); + (*line) += 3; + exc->eof = 1; + return 0; + } + + if (!exc->started) { + rnd_message(RND_MSG_ERROR, "excellon: missing M48 before header comamnd %s\n", *line); + return -1; + } + + if (strncmp(*line, "METRIC", 6) == 0) { + (*line) += 6; + if (exc->got_unit) + goto err_unit_dup; + exc->inch = 0; + exc->got_unit = 1; + if ((*line)[0] == ',') { + char *sep; + int len; + (*line)++; + sep = strchr(*line, '.'); + if (sep != NULL) { + TODO("this expects newline"); + len = strlen(*line); + len = len - (sep - (*line)) - 1; + exc->has_metric_scale = 1; + exc->metric_scale = pow(10, len); + (*line) += len; + return 0; + } + else { + rnd_message(RND_MSG_ERROR, "excellon: metric format specifier lacks decimal dot; this file is broken.\n(Assuming .2 but expect broken input)\n"); + exc->has_metric_scale = 1; + exc->metric_scale = 100; + (*line)--; /* so that *line points to ",LZ" again */ + } + } + } + + if (strncmp(*line, "INCH", 4) == 0) { + (*line) += 4; + if (exc->got_unit) + goto err_unit_dup; + + + exc->inch = 1; + exc->got_unit = 1; + return 0; + } + + if (strncmp(*line, ",LZ", 3) == 0) { + exc->leading_zero = 1; + (*line) += 3; + return 0; + } + + if ((*line)[0] == 'T') { + char *end; + long idx; + + (*line)++; + idx = strtol(*line, &end, 10); + if (idx < 1) { + rnd_message(RND_MSG_ERROR, "excellon: tool index %d out of range (0..99)\n", idx); + return -1; + } + end = strchr(end, 'C'); /* skip over S and F */ + if ((end == NULL) || (*end != 'C')) { + rnd_message(RND_MSG_ERROR, "excellon: tool separator 'C' is missing\n"); + return -1; + } + *line = end+1; + return exc_load_tool(exc, line, idx); + } + + rnd_message(RND_MSG_ERROR, "excellon: invalid line '%s' in header\n", *line); + return -1; + + err_unit_dup:; + rnd_message(RND_MSG_ERROR, "excellon: unit already set\n"); + return -1; +} + +static int exc_parse_move(exc_t *exc, char **line, char endchar) +{ + double x = exc->x, y = exc->y; + + if (**line != 'Y') { /* X is optional, when missing, Y starts the line */ + if (**line != 'X') { + rnd_message(RND_MSG_ERROR, "excellon: expected X\n"); + return -1; + } + (*line)++; + x = exc_strtod(exc, *line, line); + exc->x = exc2coord(exc, x); + } + + if (**line != '\0') { /* Y is optional */ + if (**line != 'Y') { + rnd_message(RND_MSG_ERROR, "excellon: expected Y (broken X coord?)\n"); + return -1; + } + (*line)++; + y = exc_strtod(exc, *line, line); + exc->y = exc2coord(exc, y); + } + + if (endchar != '\0') { /* requested specific termination */ + if (**line != endchar) { + rnd_message(RND_MSG_ERROR, "excellon: broken Y coord\n"); + return -1; + } + } + + return 0; +} + +static int exc_parse_line(exc_t *exc, char **line) +{ + rnd_coord_t x0 = exc->x, y0 = exc->y; + + if (exc->tool == 0) { + rnd_message(RND_MSG_ERROR, "excellon: can not drill: no tool selected\n"); + return -1; + } + + if (exc_parse_move(exc, line, '\0') != 0) + return -1; + exc_gen_line(exc, x0, y0, exc->x, exc->y); + return 0; +} + +static int exc_parse_arc(exc_t *exc, char **line, int cw) +{ + rnd_coord_t x0 = exc->x, y0 = exc->y, r; + double a; + char *end; + + if (exc->tool == 0) { + rnd_message(RND_MSG_ERROR, "excellon: can not drill: no tool selected\n"); + return -1; + } + + if (exc_parse_move(exc, line, 'A') != 0) + return -1; + a = exc_strtod(exc, *line, &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "excellon: broken A coord\n"); + return -1; + } + *line = end; + r = exc2coord(exc, a); + TODO("draw arc"); + return -1; +} + +static int exc_parse_body(exc_t *exc, char **line) +{ + int code; + + if (exc->eof) { + rnd_message(RND_MSG_ERROR, "excellon: command after M30: '%s'\n", *line); + return -1; + } + + code = ((*line)[1]-'0')*10 + ((*line)[2]-'0'); + + if ((*line)[0] == 'G') { + (*line)+=3; + switch(code) { + case 00: exc->rout = 1; return exc_parse_move(exc, line, '\0'); + case 05: expect_fmat(exc, 2); exc->rout = 0; return 0; + case 81: expect_fmat(exc, 1); exc->rout = 0; return 0; + case 01: return exc_parse_line(exc, line); + case 85: return exc_parse_line(exc, line); + case 02: return exc_parse_arc(exc, line, 1); + case 03: return exc_parse_arc(exc, line, 0); + case 90: return 0; /* ignore absolute mode */ + case 91: + rnd_message(RND_MSG_ERROR, "excellon: increment mode (G91) is not supported. Please report this bug with the file.\n"); + return -1; + + } + rnd_message(RND_MSG_ERROR, "excellon: invalid G-code: %d\n", code); + return -1; + } + + if ((*line)[0] == 'T') { + char *end; + long idx; + (*line)++; + idx = strtol(*line, &end, 10); + if (*end == 'C') { + end++; + exc->inch = 1; + if (exc->tools.used == 0) + rnd_message(RND_MSG_ERROR, "excellon: old/broken drill file (no header); expect some drills missing or mislocated\n"); + if (exc_load_tool(exc, &end, idx) != 0) { + rnd_message(RND_MSG_ERROR, "excellon: broken tool selection+specification\n"); + return -1; + } + if ((*end == 'F') || (*end == 'S')) + *end = '\0'; + } + if ((idx < 0) || (idx >= exc->tools.used)) { + rnd_message(RND_MSG_ERROR, "excellon: tool index %d out of range (0..99)\n", idx); + return -1; + } + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "excellon: broken tool selection\n"); + return -1; + } + (*line) = end; + if ((idx != 0) && (exc->tools.array[idx] == 0)) { + rnd_message(RND_MSG_ERROR, "excellon: invalid tool selection: %d is not specified\n", idx); + return -1; + } + exc->tool = idx; + return 0; + } + + if (((*line)[0] == 'X') || ((*line)[0] == 'Y')) { + if (exc->tool == 0) { + rnd_message(RND_MSG_ERROR, "excellon: can not drill: no tool selected\n"); + return -1; + } + if (exc_parse_move(exc, line, '\0') != 0) { + rnd_message(RND_MSG_ERROR, "excellon: exc_parse_move() failed\n"); + return -1; + } + exc_gen_line(exc, exc->x, exc->y, exc->x, exc->y); + return 0; + } + + if ((*line)[0] == 'M') { + (*line) += 3; + switch(code) { + case 15: exc->tool_down = 1; return 0; + case 16: exc->tool_down = 0; return 0; + case 17: exc->tool_down = 0; return 0; + case 30: exc->eof = 1; return 0; + } + } + + return -1; +} + +int camv_exc_load(camv_design_t *camv, const char *fn, FILE *f) +{ + char *end, *line, line_[1024]; + exc_t exc; + int res; + + memset(&exc, 0, sizeof(exc)); + exc.ly = camv_layer_new(); + exc.ly->name = rnd_strdup(fn); + camv_layer_invent_color(camv, exc.ly); + camv_layer_append_to_design(camv, exc.ly); + vtc0_init(&exc.tools); + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + exc.lineno++; + + while(isspace(*line)) line++; + end = strpbrk(line, "\n\r"); + if (end == NULL) { + rnd_message(RND_MSG_ERROR, "%s:%ld: Every line needs to be terminated by a newline character\n", fn, exc.lineno); + return -1; + } + *end = '\0'; + + if (*line == '\0') continue; /* ignore empty lines */ + if (*line == ';') continue; /* ignore comments */ + + while(*line != '\0') { + if (exc.inbody) + res = exc_parse_body(&exc, &line); + else + res = exc_parse_header(&exc, &line); + + if (res != 0) { + rnd_message(RND_MSG_ERROR, "(excellon error occured at %s:%ld)\n", fn, exc.lineno); + goto quit; + } + } + } + + quit:; + vtc0_uninit(&exc.tools); + return res; +} + +static int camv_exc_test_load(camv_design_t *camv, const char *fn, FILE *f) +{ + char *s, *line, line_[1024]; + int bad = 0, had_m = 0; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + while(isspace(*line)) line++; + if (*line == ';') + continue; + if ((line[0] == 'T') && !had_m) { /* drill file with no header: recognize tool selection: T1C.008F0S0 */ + s = line+1; + while(isdigit(*s)) s++; + if (s[0] == 'C') { + if (((s[1] == '.') && isdigit(s[2])) || (isdigit(s[1]))) + return 1; + } + } + if (line[0] == 'M') + had_m = 1; + if ((strncmp(line, "M48", 3) == 0) && (!isalnum(line[3]))) + return 1; + bad++; + if (bad > 16) + return 0; + } + return 0; +} + + +static camv_io_t io_exc = { + "excellon", 90, + camv_exc_test_load, + camv_exc_load, + NULL +}; + + +int pplg_check_ver_import_excellon(int ver_needed) { return 0; } + +void pplg_uninit_import_excellon(void) +{ + camv_io_unreg(&io_exc); +} + +int pplg_init_import_excellon(void) +{ + camv_io_reg(&io_exc); + return 0; +} Index: tags/1.1.4/src_plugins/import_excellon/import_excellon.pup =================================================================== --- tags/1.1.4/src_plugins/import_excellon/import_excellon.pup (nonexistent) +++ tags/1.1.4/src_plugins/import_excellon/import_excellon.pup (revision 818) @@ -0,0 +1,9 @@ +$class import +$short excellon drill files +$long Load excellon drill files (with slots) +$package import +$state works +$fmt-native no +$fmt-feature-r excellon drill files +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/import_excellon/regression/TALOS-2021-1402.gbr =================================================================== --- tags/1.1.4/src_plugins/import_excellon/regression/TALOS-2021-1402.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_excellon/regression/TALOS-2021-1402.gbr (revision 818) @@ -0,0 +1,4 @@ +% +T10000000C3 +M30 +X0 Index: tags/1.1.4/src_plugins/import_gcode/Makefile =================================================================== --- tags/1.1.4/src_plugins/import_gcode/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/Makefile (revision 818) @@ -0,0 +1,9 @@ +include ../../Makefile.conf +LIBARCHDIR=$(LIBRND_LIBARCHDIR) +CFLAGS = -DRND_PCB_COMPAT -Wall -g -I$(LIBRND_PREFIX)/include/librnd4/librnd/src_3rd +LDLIBS = -lm $(LIBRND_PREFIX)/$(LIBARCHDIR)/librnd-3rd.a + +main: main.o gcode_vm.o gcode_exec.o gcode_lex.o gcode.tab.o + +gcode.tab.c gcode.tab.h: gcode.y + byacc -v -b gcode -d -p gcode -P gcode.y Index: tags/1.1.4/src_plugins/import_gcode/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/import_gcode/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/Plug.tmpasm (revision 818) @@ -0,0 +1,18 @@ +put /local/rnd/mod {import_gcode} +put /local/rnd/mod/CONF {$(PLUGDIR)/import_gcode/import_gcode_conf.h} +put /local/rnd/mod/CONFFILE {import_gcode.conf} +put /local/rnd/mod/CONFVAR {import_gcode_conf_internal} + +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/import_gcode/import_gcode.o + $(PLUGDIR)/import_gcode/gcode_exec.o + $(PLUGDIR)/import_gcode/gcode_vm.o + $(PLUGDIR)/import_gcode/gcode_lex.o + $(PLUGDIR)/import_gcode/gcode.tab.o +@] + +switch /local/module/import_gcode/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/import_gcode/doc/LIMIT =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/LIMIT (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/LIMIT (revision 818) @@ -0,0 +1 @@ +there are no rotary axes (A;B;C) Index: tags/1.1.4/src_plugins/import_gcode/doc/canned =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/canned (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/canned (revision 818) @@ -0,0 +1,11 @@ +canned cycles: + (G98 is default) + + Z... (clearance plane for G98) + G81 X.. Y.. R... Z.. F.. (goes to X;Y, R is safe plane for G99, then down to Z at feed rate F) + (implicit: rapid back up to the clearance plane, set for G98 or G99) + X.. (drills down again to Z specified above) + X.. G99 (this one retracts to whatever R said in G81) + X.. R1.1 Z-2 (change G99 retract and Z depth) + X.. + G80 (cancel, or "break") \ No newline at end of file Index: tags/1.1.4/src_plugins/import_gcode/doc/g53 =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/g53 (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/g53 (revision 818) @@ -0,0 +1 @@ +G53 is non-modal: needs to be repeated every time Index: tags/1.1.4/src_plugins/import_gcode/doc/if =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/if (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/if (revision 818) @@ -0,0 +1,6 @@ +if [ #188 GT [ #100 + 0.01]] GOTO 3000 + +or + +if [ #188 GT 3] M30 + Index: tags/1.1.4/src_plugins/import_gcode/doc/subprog =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/subprog (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/subprog (revision 818) @@ -0,0 +1,34 @@ +plain M99 in main program is a restart + +M99 P100 is a GOTO N100 + + + +Internal subs: +~~~~~~~~~~~~~~ + +M97 P1000 (call N1000) + +... + +M30 (main program end) + +N1000 ... +M99 (ret) + + +If M97 has L.., that sets how many times it should be repeated (loop) + + +External subs: +~~~~~~~~~~~~~~ +M98 Pnnnn + +separate file Onnn.txt + +Variables: +~~~~~~~~~~ + +local (1..33) G65 A...Z +global +system Index: tags/1.1.4/src_plugins/import_gcode/doc/tool =================================================================== --- tags/1.1.4/src_plugins/import_gcode/doc/tool (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/doc/tool (revision 818) @@ -0,0 +1,6 @@ +tool selection: + +M06 T1 + +a plain T4 without M06 will pre-stage T4 but not switch to it + Index: tags/1.1.4/src_plugins/import_gcode/gcode.tab.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode.tab.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode.tab.c (revision 818) @@ -0,0 +1,890 @@ +/* original parser id follows */ +/* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */ +/* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */ + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140715 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) +#define YYENOMEM (-2) +#define YYEOF 0 + +#ifndef yyparse +#define yyparse gcodeparse +#endif /* yyparse */ + +#ifndef yylex +#define yylex gcodelex +#endif /* yylex */ + +#ifndef yyerror +#define yyerror gcodeerror +#endif /* yyerror */ + +#ifndef yychar +#define yychar gcodechar +#endif /* yychar */ + +#ifndef yyval +#define yyval gcodeval +#endif /* yyval */ + +#ifndef yylval +#define yylval gcodelval +#endif /* yylval */ + +#ifndef yydebug +#define yydebug gcodedebug +#endif /* yydebug */ + +#ifndef yynerrs +#define yynerrs gcodenerrs +#endif /* yynerrs */ + +#ifndef yyerrflag +#define yyerrflag gcodeerrflag +#endif /* yyerrflag */ + +#ifndef yylhs +#define yylhs gcodelhs +#endif /* yylhs */ + +#ifndef yylen +#define yylen gcodelen +#endif /* yylen */ + +#ifndef yydefred +#define yydefred gcodedefred +#endif /* yydefred */ + +#ifndef yydgoto +#define yydgoto gcodedgoto +#endif /* yydgoto */ + +#ifndef yysindex +#define yysindex gcodesindex +#endif /* yysindex */ + +#ifndef yyrindex +#define yyrindex gcoderindex +#endif /* yyrindex */ + +#ifndef yygindex +#define yygindex gcodegindex +#endif /* yygindex */ + +#ifndef yytable +#define yytable gcodetable +#endif /* yytable */ + +#ifndef yycheck +#define yycheck gcodecheck +#endif /* yycheck */ + +#ifndef yyname +#define yyname gcodename +#endif /* yyname */ + +#ifndef yyrule +#define yyrule gcoderule +#endif /* yyrule */ +#define YYPREFIX "gcode" + +#define YYPURE 1 + +#line 2 "gcode.y" +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "gcode_vm.h" +#include "gcode_lex.h" +#line 36 "gcode.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + double num; + int chr; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +#line 143 "gcode.tab.c" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(gcode_prg_t * ctx) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# ifdef YYLEX_PARAM_TYPE +# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLEX_PARAM_TYPE YYLEX_PARAM) +# else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, void * YYLEX_PARAM) +# endif +# define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, gcode_prg_t * ctx) +# define YYLEX yylex(&yylval, ctx) +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(gcode_prg_t * ctx, const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(ctx, msg) +#endif + +extern int YYPARSE_DECL(); + +#define T_NUM 257 +#define T_DEC 258 +#define T_CHR 259 +#define T_NL 260 +#define T_LINENO 261 +#define T_ACOS 262 +#define T_ASIN 263 +#define T_ATAN 264 +#define T_ABS 265 +#define T_COS 266 +#define T_SIN 267 +#define T_TAN 268 +#define T_FIX 269 +#define T_FUP 270 +#define T_EXP 271 +#define T_LN 272 +#define T_ROUND 273 +#define T_SQRT 274 +#define T_MOD 275 +#define UMINUS 276 +#define UPLUS 277 +#define T_OR 278 +#define T_XOR 279 +#define T_AND 280 +#define YYERRCODE 256 +typedef short YYINT; +static const YYINT gcodelhs[] = { -1, + 0, 0, 1, 3, 1, 4, 1, 2, 2, 5, + 5, 5, 5, 5, 7, 5, 6, 8, 6, 9, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, +}; +static const YYINT gcodelen[] = { 2, + 2, 0, 1, 0, 5, 0, 3, 1, 2, 4, + 3, 2, 2, 3, 0, 5, 3, 0, 3, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 1, 1, +}; +static const YYINT gcodedefred[] = { 0, + 3, 0, 0, 0, 0, 4, 1, 0, 15, 0, + 0, 0, 13, 12, 0, 0, 0, 0, 7, 9, + 0, 14, 44, 45, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 20, 18, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, + 0, 0, 0, 26, 27, 28, 0, 33, 34, 0, + 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 0, 0, 0, 32, +}; +static const YYINT gcodedgoto[] = { 3, + 4, 10, 12, 5, 11, 42, 18, 60, 59, +}; +static const YYINT gcodesindex[] = { -213, + 0, -255, 0, -213, -26, 0, 0, 10, 0, -245, + -26, -26, 0, 0, -252, 18, 18, 18, 0, 0, + -238, 0, 0, 0, -71, -63, -39, -37, -34, -32, + -6, -4, -2, 4, 6, 12, 16, 0, 0, 18, + 18, 131, 23, 29, 0, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 35, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 18, 41, 51, 57, 63, 70, 76, 82, 88, + 94, 100, 106, 112, 119, -240, -240, 0, 137, 137, + -240, -240, -240, 0, 0, 0, 131, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 20, 18, 125, 0, +}; +static const YYINT gcoderindex[] = { 1, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + -198, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -35, -29, 0, -24, 159, + -18, -12, -1, 0, 0, 0, -31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +}; +static const YYINT gcodegindex[] = { 69, + 0, 39, 0, 0, 0, 384, 0, 0, 0, +}; +#define YYTABLESIZE 496 +static const YYINT gcodetable[] = { 21, + 2, 11, 6, 16, 22, 19, 21, 21, 9, 21, + 22, 21, 19, 19, 19, 19, 24, 19, 22, 46, + 22, 45, 25, 24, 24, 21, 24, 47, 24, 25, + 25, 19, 25, 29, 25, 6, 22, 68, 69, 70, + 29, 29, 24, 29, 16, 29, 1, 2, 25, 20, + 21, 48, 40, 49, 15, 111, 50, 21, 51, 29, + 38, 8, 39, 19, 65, 63, 0, 64, 22, 66, + 65, 63, 7, 64, 24, 66, 65, 63, 0, 64, + 25, 66, 65, 63, 52, 64, 53, 66, 54, 72, + 0, 29, 65, 63, 55, 64, 56, 66, 65, 63, + 17, 64, 57, 66, 65, 63, 58, 64, 41, 66, + 112, 65, 63, 0, 64, 71, 66, 65, 63, 0, + 64, 0, 66, 65, 63, 0, 64, 88, 66, 65, + 63, 0, 64, 98, 66, 65, 63, 0, 64, 0, + 66, 65, 63, 99, 64, 0, 66, 65, 63, 100, + 64, 0, 66, 65, 63, 101, 64, 0, 66, 0, + 65, 63, 102, 64, 0, 66, 65, 63, 103, 64, + 0, 66, 65, 63, 104, 64, 0, 66, 65, 0, + 105, 0, 0, 66, 0, 0, 106, 0, 0, 0, + 0, 0, 107, 23, 0, 0, 0, 0, 108, 0, + 0, 23, 0, 23, 109, 0, 0, 0, 0, 0, + 0, 110, 0, 0, 0, 0, 0, 114, 0, 23, + 0, 0, 0, 21, 21, 11, 11, 16, 16, 19, + 19, 0, 8, 0, 22, 22, 0, 0, 0, 21, + 24, 24, 0, 0, 0, 19, 25, 25, 0, 0, + 0, 23, 0, 0, 0, 0, 24, 29, 29, 6, + 0, 0, 25, 0, 0, 0, 13, 14, 0, 0, + 0, 0, 0, 29, 23, 24, 0, 0, 0, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 0, 0, 0, 0, 0, 67, 0, 0, + 68, 69, 70, 67, 0, 0, 68, 69, 70, 67, + 0, 0, 68, 69, 70, 67, 0, 0, 68, 69, + 70, 0, 0, 0, 0, 67, 0, 0, 68, 69, + 70, 67, 0, 0, 68, 69, 70, 67, 0, 0, + 68, 69, 70, 0, 67, 0, 0, 68, 69, 70, + 67, 0, 0, 68, 69, 70, 67, 0, 0, 68, + 69, 70, 67, 0, 0, 68, 69, 70, 67, 0, + 0, 68, 69, 70, 67, 0, 0, 68, 69, 70, + 67, 0, 0, 68, 69, 70, 67, 0, 0, 68, + 69, 70, 0, 67, 0, 0, 68, 69, 70, 67, + 43, 44, 68, 69, 70, 67, 0, 0, 68, 69, + 70, 67, 0, 0, 68, 69, 70, 23, 23, 0, + 0, 0, 0, 61, 62, 0, 0, 0, 0, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 0, 0, 89, 90, 91, 92, + 93, 94, 95, 96, 0, 97, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 113, +}; +static const YYINT gcodecheck[] = { 35, + 0, 35, 258, 35, 257, 35, 42, 43, 35, 45, + 35, 47, 42, 43, 260, 45, 35, 47, 43, 91, + 45, 260, 35, 42, 43, 61, 45, 91, 47, 42, + 43, 61, 45, 35, 47, 35, 61, 278, 279, 280, + 42, 43, 61, 45, 35, 47, 260, 261, 61, 11, + 12, 91, 35, 91, 45, 47, 91, 93, 91, 61, + 43, 260, 45, 93, 42, 43, -1, 45, 93, 47, + 42, 43, 4, 45, 93, 47, 42, 43, -1, 45, + 93, 47, 42, 43, 91, 45, 91, 47, 91, 61, + -1, 93, 42, 43, 91, 45, 91, 47, 42, 43, + 91, 45, 91, 47, 42, 43, 91, 45, 91, 47, + 91, 42, 43, -1, 45, 93, 47, 42, 43, -1, + 45, -1, 47, 42, 43, -1, 45, 93, 47, 42, + 43, -1, 45, 93, 47, 42, 43, -1, 45, -1, + 47, 42, 43, 93, 45, -1, 47, 42, 43, 93, + 45, -1, 47, 42, 43, 93, 45, -1, 47, -1, + 42, 43, 93, 45, -1, 47, 42, 43, 93, 45, + -1, 47, 42, 43, 93, 45, -1, 47, 42, -1, + 93, -1, -1, 47, -1, -1, 93, -1, -1, -1, + -1, -1, 93, 35, -1, -1, -1, -1, 93, -1, + -1, 43, -1, 45, 93, -1, -1, -1, -1, -1, + -1, 93, -1, -1, -1, -1, -1, 93, -1, 61, + -1, -1, -1, 259, 260, 259, 260, 259, 260, 259, + 260, -1, 259, -1, 259, 260, -1, -1, -1, 275, + 259, 260, -1, -1, -1, 275, 259, 260, -1, -1, + -1, 93, -1, -1, -1, -1, 275, 259, 260, 259, + -1, -1, 275, -1, -1, -1, 257, 258, -1, -1, + -1, -1, -1, 275, 257, 258, -1, -1, -1, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, -1, -1, -1, -1, -1, 275, -1, -1, + 278, 279, 280, 275, -1, -1, 278, 279, 280, 275, + -1, -1, 278, 279, 280, 275, -1, -1, 278, 279, + 280, -1, -1, -1, -1, 275, -1, -1, 278, 279, + 280, 275, -1, -1, 278, 279, 280, 275, -1, -1, + 278, 279, 280, -1, 275, -1, -1, 278, 279, 280, + 275, -1, -1, 278, 279, 280, 275, -1, -1, 278, + 279, 280, 275, -1, -1, 278, 279, 280, 275, -1, + -1, 278, 279, 280, 275, -1, -1, 278, 279, 280, + 275, -1, -1, 278, 279, 280, 275, -1, -1, 278, + 279, 280, -1, 275, -1, -1, 278, 279, 280, 275, + 17, 18, 278, 279, 280, 275, -1, -1, 278, 279, + 280, 275, -1, -1, 278, 279, 280, 259, 260, -1, + -1, -1, -1, 40, 41, -1, -1, -1, -1, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 112, +}; +#define YYFINAL 3 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 280 +#define YYUNDFTOKEN 292 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) +#if YYDEBUG +static const char *const gcodename[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,"'#'",0,0,0,0,0,0,"'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,0,"'='", +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'['",0,"']'",0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +"T_NUM","T_DEC","T_CHR","T_NL","T_LINENO","T_ACOS","T_ASIN","T_ATAN","T_ABS", +"T_COS","T_SIN","T_TAN","T_FIX","T_FUP","T_EXP","T_LN","T_ROUND","T_SQRT", +"T_MOD","UMINUS","UPLUS","T_OR","T_XOR","T_AND",0,0,0,0,0,0,0,0,0,0,0, +"illegal-symbol", +}; +static const char *const gcoderule[] = { +"$accept : program", +"program : line program", +"program :", +"line : T_NL", +"$$1 :", +"line : T_LINENO T_DEC $$1 codes T_NL", +"$$2 :", +"line : $$2 codes T_NL", +"codes : gcode", +"codes : gcode codes", +"gcode : T_CHR '[' expr ']'", +"gcode : T_CHR '#' expr", +"gcode : T_CHR T_DEC", +"gcode : T_CHR T_NUM", +"gcode : T_CHR '-' T_NUM", +"$$3 :", +"gcode : '#' $$3 expr '=' expr", +"expr : '[' expr ']'", +"$$4 :", +"expr : '-' $$4 expr", +"$$5 :", +"expr : '+' $$5 expr", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr T_OR expr", +"expr : expr T_XOR expr", +"expr : expr T_AND expr", +"expr : expr T_MOD expr", +"expr : '#' expr", +"expr : T_ABS '[' expr ']'", +"expr : T_ATAN '[' expr ']' '/' '[' expr ']'", +"expr : T_ACOS '[' expr ']'", +"expr : T_ASIN '[' expr ']'", +"expr : T_COS '[' expr ']'", +"expr : T_SIN '[' expr ']'", +"expr : T_TAN '[' expr ']'", +"expr : T_FIX '[' expr ']'", +"expr : T_FUP '[' expr ']'", +"expr : T_EXP '[' expr ']'", +"expr : T_LN '[' expr ']'", +"expr : T_ROUND '[' expr ']'", +"expr : T_SQRT '[' expr ']'", +"expr : T_NUM", +"expr : T_DEC", + +}; +#endif + +int yydebug; +int yynerrs; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + YYINT *s_base; + YYINT *s_mark; + YYINT *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; + +#if YYDEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + YYINT *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return YYENOMEM; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return YYENOMEM; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return YYENOMEM; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yyerrflag; + int yychar; + YYSTYPE yyval; + YYSTYPE yylval; + + /* variables for the parser stack */ + YYSTACKDATA yystack; + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = YYEOF; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + YYERROR_CALL("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == YYEOF) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 4: +#line 63 "gcode.y" + { gcode_set_lineno(ctx, (int)yystack.l_mark[0].num); gcode_append(ctx, T_LINENO, yystack.l_mark[0].num); } +break; +case 5: +#line 64 "gcode.y" + { gcode_delayed(ctx, GCP_DELAY_APPLY); gcode_delayed(ctx, GCP_DELAY_OFF); gcode_append(ctx, DO, -1); } +break; +case 6: +#line 65 "gcode.y" + { gcode_append(ctx, T_LINENO, -1); ctx->lineno = -1; } +break; +case 7: +#line 66 "gcode.y" + { gcode_delayed(ctx, GCP_DELAY_APPLY); gcode_delayed(ctx, GCP_DELAY_OFF); gcode_append(ctx, DO, -1); } +break; +case 10: +#line 75 "gcode.y" + { gcode_append(ctx, yystack.l_mark[-3].chr, -1); } +break; +case 11: +#line 76 "gcode.y" + { gcode_append(ctx, PARAM, 0); gcode_append(ctx, yystack.l_mark[-2].chr, -1); } +break; +case 12: +#line 77 "gcode.y" + { gcode_append(ctx, yystack.l_mark[-1].chr, yystack.l_mark[0].num); } +break; +case 13: +#line 78 "gcode.y" + { gcode_append(ctx, yystack.l_mark[-1].chr, yystack.l_mark[0].num); } +break; +case 14: +#line 79 "gcode.y" + { gcode_append(ctx, yystack.l_mark[-2].chr, -(yystack.l_mark[0].num)); } +break; +case 15: +#line 81 "gcode.y" + { gcode_delayed(ctx, GCP_DELAY_ON); } +break; +case 16: +#line 83 "gcode.y" + { gcode_append(ctx, ASSIGN, 0); gcode_delayed(ctx, GCP_DELAY_OFF); } +break; +case 18: +#line 88 "gcode.y" + { gcode_append(ctx, PUSH_NUM, 0); } +break; +case 19: +#line 89 "gcode.y" + { gcode_append(ctx, SUB, 0); } +break; +case 20: +#line 90 "gcode.y" + { /* nothing to do */ } +break; +case 22: +#line 92 "gcode.y" + { gcode_append(ctx, ADD, 0); } +break; +case 23: +#line 93 "gcode.y" + { gcode_append(ctx, SUB, 0); } +break; +case 24: +#line 94 "gcode.y" + { gcode_append(ctx, MUL, 0); } +break; +case 25: +#line 95 "gcode.y" + { gcode_append(ctx, DIV, 0); } +break; +case 26: +#line 96 "gcode.y" + { gcode_append(ctx, T_OR, 0); } +break; +case 27: +#line 97 "gcode.y" + { gcode_append(ctx, T_XOR, 0); } +break; +case 28: +#line 98 "gcode.y" + { gcode_append(ctx, T_AND, 0); } +break; +case 29: +#line 99 "gcode.y" + { gcode_append(ctx, T_MOD, 0); } +break; +case 30: +#line 100 "gcode.y" + { gcode_append(ctx, PARAM, 0); } +break; +case 31: +#line 101 "gcode.y" + { gcode_append(ctx, T_ABS, 0); } +break; +case 32: +#line 103 "gcode.y" + { gcode_append(ctx, T_ATAN, 0); } +break; +case 33: +#line 104 "gcode.y" + { gcode_append(ctx, T_ACOS, 0); } +break; +case 34: +#line 105 "gcode.y" + { gcode_append(ctx, T_ASIN, 0); } +break; +case 35: +#line 106 "gcode.y" + { gcode_append(ctx, T_COS, 0); } +break; +case 36: +#line 107 "gcode.y" + { gcode_append(ctx, T_SIN, 0); } +break; +case 37: +#line 108 "gcode.y" + { gcode_append(ctx, T_TAN, 0); } +break; +case 38: +#line 109 "gcode.y" + { gcode_append(ctx, T_FIX, 0); } +break; +case 39: +#line 110 "gcode.y" + { gcode_append(ctx, T_FUP, 0); } +break; +case 40: +#line 111 "gcode.y" + { gcode_append(ctx, T_EXP, 0); } +break; +case 41: +#line 112 "gcode.y" + { gcode_append(ctx, T_LN, 0); } +break; +case 42: +#line 113 "gcode.y" + { gcode_append(ctx, T_ROUND, 0); } +break; +case 43: +#line 114 "gcode.y" + { gcode_append(ctx, T_SQRT, 0); } +break; +case 44: +#line 115 "gcode.y" + { gcode_append(ctx, PUSH_NUM, yystack.l_mark[0].num); } +break; +case 45: +#line 116 "gcode.y" + { gcode_append(ctx, PUSH_NUM, yystack.l_mark[0].num); } +break; +#line 832 "gcode.tab.c" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = YYEOF; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == YYEOF) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + *++yystack.s_mark = (YYINT) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + YYERROR_CALL("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} Index: tags/1.1.4/src_plugins/import_gcode/gcode.tab.h =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode.tab.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode.tab.h (revision 818) @@ -0,0 +1,36 @@ +#define T_NUM 257 +#define T_DEC 258 +#define T_CHR 259 +#define T_NL 260 +#define T_LINENO 261 +#define T_ACOS 262 +#define T_ASIN 263 +#define T_ATAN 264 +#define T_ABS 265 +#define T_COS 266 +#define T_SIN 267 +#define T_TAN 268 +#define T_FIX 269 +#define T_FUP 270 +#define T_EXP 271 +#define T_LN 272 +#define T_ROUND 273 +#define T_SQRT 274 +#define T_MOD 275 +#define UMINUS 276 +#define UPLUS 277 +#define T_OR 278 +#define T_XOR 279 +#define T_AND 280 +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + double num; + int chr; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +extern YYSTYPE gcodelval; Index: tags/1.1.4/src_plugins/import_gcode/gcode.y =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode.y (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode.y (revision 818) @@ -0,0 +1,119 @@ +%{ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "gcode_vm.h" +#include "gcode_lex.h" +%} + +%lex-param { gcode_prg_t *ctx } +%parse-param { gcode_prg_t *ctx } + +%union { + double num; + int chr; +} + +%token T_NUM +%token T_DEC +%token T_CHR +%token T_NL T_LINENO +%token T_ACOS T_ASIN T_ATAN T_ABS T_COS T_SIN T_TAN +%token T_FIX T_FUP T_EXP T_LN T_ROUND T_SQRT + +%left '+' '-' +%left '*' '/' T_MOD +%left UMINUS UPLUS +%left T_OR T_XOR T_AND +%left '#' + +%% + +program: + line program + | /* empty */ + ; + +line: + T_NL + | T_LINENO T_DEC { gcode_set_lineno(ctx, (int)$2); gcode_append(ctx, T_LINENO, $2); } + codes T_NL { gcode_delayed(ctx, GCP_DELAY_APPLY); gcode_delayed(ctx, GCP_DELAY_OFF); gcode_append(ctx, DO, -1); } + | { gcode_append(ctx, T_LINENO, -1); ctx->lineno = -1; } + codes T_NL { gcode_delayed(ctx, GCP_DELAY_APPLY); gcode_delayed(ctx, GCP_DELAY_OFF); gcode_append(ctx, DO, -1); } + ; + +codes: + gcode + | gcode codes + ; + +gcode: + T_CHR '[' expr ']' { gcode_append(ctx, $1, -1); } + | T_CHR '#' expr { gcode_append(ctx, PARAM, 0); gcode_append(ctx, $1, -1); } + | T_CHR T_DEC { gcode_append(ctx, $1, $2); } + | T_CHR T_NUM { gcode_append(ctx, $1, $2); } + | T_CHR '-' T_NUM { gcode_append(ctx, $1, -($3)); } + | '#' + { gcode_delayed(ctx, GCP_DELAY_ON); } /* assignment needs to be executed at the end of the line (by the spec) */ + expr '=' expr + { gcode_append(ctx, ASSIGN, 0); gcode_delayed(ctx, GCP_DELAY_OFF); } + ; + +expr: + '[' expr ']' + | '-' { gcode_append(ctx, PUSH_NUM, 0); } + expr %prec UMINUS { gcode_append(ctx, SUB, 0); } + | '+' { /* nothing to do */ } + expr %prec UPLUS + | expr '+' expr { gcode_append(ctx, ADD, 0); } + | expr '-' expr { gcode_append(ctx, SUB, 0); } + | expr '*' expr { gcode_append(ctx, MUL, 0); } + | expr '/' expr { gcode_append(ctx, DIV, 0); } + | expr T_OR expr { gcode_append(ctx, T_OR, 0); } + | expr T_XOR expr { gcode_append(ctx, T_XOR, 0); } + | expr T_AND expr { gcode_append(ctx, T_AND, 0); } + | expr T_MOD expr { gcode_append(ctx, T_MOD, 0); } + | '#' expr { gcode_append(ctx, PARAM, 0); } + | T_ABS '[' expr ']' { gcode_append(ctx, T_ABS, 0); } + | T_ATAN '[' expr ']' '/' + '[' expr ']' { gcode_append(ctx, T_ATAN, 0); } + | T_ACOS '[' expr ']' { gcode_append(ctx, T_ACOS, 0); } + | T_ASIN '[' expr ']' { gcode_append(ctx, T_ASIN, 0); } + | T_COS '[' expr ']' { gcode_append(ctx, T_COS, 0); } + | T_SIN '[' expr ']' { gcode_append(ctx, T_SIN, 0); } + | T_TAN '[' expr ']' { gcode_append(ctx, T_TAN, 0); } + | T_FIX '[' expr ']' { gcode_append(ctx, T_FIX, 0); } + | T_FUP '[' expr ']' { gcode_append(ctx, T_FUP, 0); } + | T_EXP '[' expr ']' { gcode_append(ctx, T_EXP, 0); } + | T_LN '[' expr ']' { gcode_append(ctx, T_LN, 0); } + | T_ROUND '[' expr ']' { gcode_append(ctx, T_ROUND, 0); } + | T_SQRT '[' expr ']' { gcode_append(ctx, T_SQRT, 0); } + | T_NUM { gcode_append(ctx, PUSH_NUM, $1); } + | T_DEC { gcode_append(ctx, PUSH_NUM, $1); } + ; + +%% Index: tags/1.1.4/src_plugins/import_gcode/gcode_exec.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_exec.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_exec.c (revision 818) @@ -0,0 +1,287 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +TODO("remove this") +#include + +#include "gcode_vm.h" +#include "gcode_exec.h" + + +typedef enum { + MOVE_TRAVEL, + MOVE_LINEAR, + MOVE_CW, + MOVE_CCW, + MOVE_NOP +} move_t; + +typedef struct { + double x, y, z; + double ox, oy, oz; /* current coordinate system offsets by the program coord system */ + double ox92, oy92, oz92; /* current coordinate system offsets by G92*/ + double tool_dia; + unsigned imperial:1; + unsigned stop:1; + unsigned relative:1; + move_t move; +} g_state_t; + +typedef struct gcode_exec_s { + const gcode_execute_op_t *ops; + g_state_t last_state, state; + double reg['Z'-'A'+1]; + char reg_set['Z'-'A'+1]; + struct { + unsigned setcrd10:1; /* G10 */ + unsigned setcrd92:1; /* G92 */ + unsigned move:1; + unsigned home:1; + unsigned home_idx:1; /* home position index is reg P when home == 1 */ + int pcs; /* program coordinate system index */ + } cmd; + double px[10], py[10], pz[10]; /* program coordinate systems (G54...G59); 0 is for G53, and is always 0;0;0 */ +} gcode_exec_t; + + +void gcode_execute_init(gcode_prg_t *prg, const gcode_execute_op_t *ops) +{ + gcode_exec_t *ctx; + prg->exec_data = ctx = calloc(sizeof(gcode_exec_t), 1); + prg->execute_code = gcode_execute_code; + ctx->ops = ops; +} + +void gcode_execute_uninit(gcode_prg_t *prg) +{ + free(prg->exec_data); +} + +static double COORD(gcode_exec_t *ctx, double last, double v) +{ + if (ctx->state.imperial) v = v * 25.4; + if (ctx->state.relative) v += last; + return v; +} + +#define CRD2REAL(st, axis) (st.axis + st.o ## axis + st.o ## axis ## 92) + +/* Execute order: of relevant commands: + T (executed in gcode_execute_code_()) + M6 (executed/ignored in gcode_execute_code_()) + G20,G21 (executed in gcode_execute_code_()) + G54..G59.* (executed in gcode_execute_code_()) + G90,G91 (executed in gcode_execute_code_()) + G28,G30 | G10 | G92* STEP1 + G0,G1,G2,G3,G80..G89 plus G53 STEP2 + M0,M1,M2,M30,M60 STEP3 +*/ +static int gcode_execute_code_do(gcode_prg_t *prg) +{ + gcode_exec_t *ctx = prg->exec_data; + + +/* printf("EXEC DO ---\n");*/ + + /* update x;y;z */ + ctx->state.x = COORD(ctx, ctx->last_state.x, ctx->reg['X'-'A']); + ctx->state.y = COORD(ctx, ctx->last_state.y, ctx->reg['Y'-'A']); + ctx->state.z = COORD(ctx, ctx->last_state.z, ctx->reg['Z'-'A']); + + /* STEP1 */ + if (ctx->cmd.home) { + int idx = 0; + + ctx->ops->travel(prg, CRD2REAL(ctx->last_state, x), CRD2REAL(ctx->last_state, y), CRD2REAL(ctx->last_state, z), CRD2REAL(ctx->state, x), CRD2REAL(ctx->state, y), CRD2REAL(ctx->state, z)); + if (ctx->cmd.home_idx) + idx = (int)ctx->reg['P'-'A']; + if (idx > 1) { + prg->error(prg, 1, "Invalid home index (only one is supported for now)"); + return -1; + } + + ctx->state.x = prg->params[5161+20*idx]; + ctx->state.y = prg->params[5162+20*idx]; + ctx->state.z = prg->params[5163+20*idx]; + ctx->ops->travel(prg, CRD2REAL(ctx->last_state, x), CRD2REAL(ctx->last_state, y), CRD2REAL(ctx->last_state, z), CRD2REAL(ctx->state, x), CRD2REAL(ctx->state, y), CRD2REAL(ctx->state, z)); + + if (ctx->cmd.setcrd10) { + prg->error(prg, 1, "can't use G10 and homing in the same line!"); + return -1; + } + } + else if (ctx->cmd.setcrd10) { + int idx; + if (ctx->reg['L'-'A'] != 2) { + prg->error(prg, 1, "G10 requires L2"); + return -1; + } + idx = (int)ctx->reg['P'-'A']; + if ((idx < 1) || (idx > 9)) { + prg->error(prg, 1, "Invalid P value for G10 L2 - must be between 1 and 9"); + return -1; + } + if (ctx->state.relative) { + prg->error(prg, 1, "Can not use G10 with relative coordinates"); + return -1; + } + ctx->px[idx] = CRD2REAL(ctx->last_state, x) - COORD(ctx, 0, ctx->reg['X'-'A']); + ctx->py[idx] = CRD2REAL(ctx->last_state, y) - COORD(ctx, 0, ctx->reg['Y'-'A']); + ctx->pz[idx] = CRD2REAL(ctx->last_state, z) - COORD(ctx, 0, ctx->reg['Z'-'A']); + } + else if (ctx->cmd.setcrd92) { + if (ctx->state.relative) { + prg->error(prg, 1, "Can not use G92 with relative coordinates"); + return -1; + } + if (!ctx->reg_set['X'-'A'] && !ctx->reg_set['Y'-'A'] && !ctx->reg_set['Z'-'A']) { + prg->error(prg, 1, "At least one of X, Y or Z is needed for G92"); + return -1; + } + ctx->state.ox92 = CRD2REAL(ctx->last_state, x) - COORD(ctx, 0, ctx->reg['X'-'A']); + ctx->state.oy92 = CRD2REAL(ctx->last_state, y) - COORD(ctx, 0, ctx->reg['Y'-'A']); + ctx->state.oz92 = CRD2REAL(ctx->last_state, z) - COORD(ctx, 0, ctx->reg['Z'-'A']); + } + + /* STEP2 */ + if (ctx->reg_set['X'-'A'] || ctx->reg_set['Y'-'A'] || ctx->reg_set['Z'-'A']) { + switch(ctx->state.move) { + case MOVE_TRAVEL: ctx->ops->travel(prg, CRD2REAL(ctx->last_state, x), CRD2REAL(ctx->last_state, y), CRD2REAL(ctx->last_state, z), CRD2REAL(ctx->state, x), CRD2REAL(ctx->state, y), CRD2REAL(ctx->state, z)); break; + case MOVE_LINEAR: ctx->ops->linear(prg, CRD2REAL(ctx->last_state, x), CRD2REAL(ctx->last_state, y), CRD2REAL(ctx->last_state, z), CRD2REAL(ctx->state, x), CRD2REAL(ctx->state, y), CRD2REAL(ctx->state, z)); break; + case MOVE_CW: + case MOVE_CCW: + prg->error(prg, 1, "arc not yet implemented"); + break; + case MOVE_NOP: break; + } + } + + + /* update state */ + ctx->last_state = ctx->state; + + /* reset per line states */ + memset(ctx->reg_set, 0, sizeof(ctx->reg_set)); + memset(&ctx->cmd, 0, sizeof(ctx->cmd)); + + /* STEP3 */ + return ctx->state.stop; +} + +#define CN(code,num) (unsigned)((((unsigned)code << 16) | (unsigned)((double)num*10.0))) + +static int gcode_execute_code_(gcode_prg_t *prg, int code, double param) +{ + gcode_exec_t *ctx = prg->exec_data; + + if ((code == 'G') || (code == 'M')) { + switch(CN(code, param)) { + case CN('G', 0): ctx->state.move = MOVE_TRAVEL; ctx->cmd.move = 1; break; + case CN('G', 1): ctx->state.move = (!prg->cfg.laser || prg->laser_on) ? MOVE_LINEAR : MOVE_TRAVEL; ctx->cmd.move = 1; break; + case CN('G', 2): ctx->state.move = MOVE_CW; ctx->cmd.move = 1; break; + case CN('G', 3): ctx->state.move = MOVE_CCW; ctx->cmd.move = 1; break; + case CN('G', 4): ctx->state.move = MOVE_NOP; ctx->cmd.move = 1; break; /* dwell */ + + case CN('G', 10): ctx->cmd.setcrd10 = 1; break; + + case CN('G', 17): break; + case CN('G', 18): case CN('G', 19): prg->error(prg, 1, "Only the XY plane is supported - no 3d milling!"); return -1; + + case CN('G', 20): ctx->state.imperial = 1; break; + case CN('G', 21): ctx->state.imperial = 0; break; + + case CN('G', 28): ctx->cmd.home = 1; ctx->cmd.home_idx = 0; break; + case CN('G', 30): ctx->cmd.home = 1; ctx->cmd.home_idx = 1; break; + + case CN('G', 41): case CN('G', 42): case CN('G', 43): case CN('G', 44): case CN('G', 49): prg->error(prg, 1, "Tool compensation not supported"); return -1; + + case CN('G', 53): ctx->cmd.pcs = 0; break; + case CN('G', 54): ctx->cmd.pcs = 1; break; + case CN('G', 55): ctx->cmd.pcs = 2; break; + case CN('G', 56): ctx->cmd.pcs = 3; break; + case CN('G', 57): ctx->cmd.pcs = 4; break; + case CN('G', 58): ctx->cmd.pcs = 5; break; + case CN('G', 59): ctx->cmd.pcs = 6; break; + case CN('G', 59.1): ctx->cmd.pcs = 7; break; + case CN('G', 59.2): ctx->cmd.pcs = 8; break; + case CN('G', 59.3): ctx->cmd.pcs = 9; break; + + case CN('G', 61): case CN('G', 64): break; /* corner physics */ + + case CN('G', 90): ctx->state.relative = 0; break; + case CN('G', 91): ctx->state.relative = 1; break; + + case CN('G', 92): ctx->cmd.setcrd92 = 1; break; + case CN('G', 92.1): case CN('G', 92.2): + case CN('G', 92.3): case CN('G', 92.4): prg->error(prg, 1, "G92.* not supported"); return -1; + + case CN('G', 95): case CN('G', 96): case CN('G', 97): break; /* ignore spindle/feed speed */ + + case CN('M', 1): case CN('M', 60): break; /* temporary program stop */ + case CN('M', 0): case CN('M', 2): case CN('M', 30): ctx->state.stop = 1; break; + + /* spindle start/stop: draw on/off for laser, ignore for anything else */ + case CN('M', 3): case CN('M', 4): if (prg->cfg.laser) prg->laser_on = 1; break; + case CN('M', 5): if (prg->cfg.laser) prg->laser_on = 0; break; + + case CN('M', 7): case CN('M', 8): case CN('M', 9): break; /* ignore coolant */ + case CN('M', 10): case CN('M', 11): break; /* ignore pallet clamp */ + case CN('M', 13): break; /* ignore spindle+coolant */ + case CN('M', 48): case CN('M', 49): break; /* ignore feedrate */ + case CN('M', 52): break; /* ignore tool unload */ + + default: + { + char tmp[256]; + sprintf(tmp, "WARNING: unhandleg code: %c%d", code, (int)param); + prg->error(prg, 1, tmp); + } + } + } + else { + ctx->reg[code - 'A'] = param; + ctx->reg_set[code - 'A'] = 1; + switch(code) { + case 'T': +TODO("tool code: tools[(int)param];"); + ctx->state.tool_dia = 1; + break; + } + } + +/* printf("EXEC %c %f\n", code, param); */ + return 0; +} + + +int gcode_execute_code(gcode_prg_t *prg, int code, double param) +{ + if (code == DO) + return gcode_execute_code_do(prg); + return gcode_execute_code_(prg, code, param); +} + Index: tags/1.1.4/src_plugins/import_gcode/gcode_exec.h =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_exec.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_exec.h (revision 818) @@ -0,0 +1,10 @@ +typedef struct { + void (*travel)(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2); + void (*linear)(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2); +} gcode_execute_op_t; + +int gcode_execute_code(gcode_prg_t *prg, int code, double param); + +void gcode_execute_init(gcode_prg_t *prg, const gcode_execute_op_t *ops); +void gcode_execute_uninit(gcode_prg_t *prg); + Index: tags/1.1.4/src_plugins/import_gcode/gcode_lex.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_lex.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_lex.c (revision 818) @@ -0,0 +1,220 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include +#include +#include "gcode_vm.h" +#include "gcode_lex.h" + +int gcodeerror(gcode_prg_t *ctx, const char *msg) +{ + char tmp[256]; + if (!ctx->subseq_error) { + sprintf(tmp, "gcode error at %ld:%ld: ", ctx->line, ctx->col); + ctx->error(ctx, 0, tmp); + ctx->subseq_error = 1; + } + ctx->error(ctx, 0, msg); + return 0; +} + +/* Most of the lexer code is borrowed from fawk (and is relicensed by the author */ +#define append(chr, bad) \ +do { \ + if (ctx->used >= ctx->alloced) { \ + char *bf; \ + ctx->alloced += 256; \ + if ((bf = realloc(ctx->buff, ctx->alloced)) == NULL) { ctx->alloced = 0; bad; } \ + ctx->buff = bf; \ + } \ + ctx->buff[ctx->used++] = chr; \ +} while(0) + +static int getch(gcode_prg_t *ctx) +{ + int ret; + if (ctx->pushback > 0) { + ret = ctx->pushback; + ctx->pushback = -1; + } + else + ret = ctx->get_char(ctx); + if (ret == EOF) ctx->in_eof = 1; + else if (ret == '\n') { ctx->line++; ctx->col = 0; } + else { ctx->col++; } + return ret; +} + +static void ungetch(gcode_prg_t *ctx, int chr) +{ + assert(ctx->pushback <= 0); + ctx->pushback = chr; + if (chr == '\n') { ctx->line--; ctx->col = 1000; } + else ctx->col--; +} + +#define del_last() ctx->used-- + +static int read_numeric(gcode_prg_t *ctx, YYSTYPE *lval, int had_decimal_dot) +{ + int chr, chr2, had_e = 0; + + next:; + chr = getch(ctx); append(chr, return -1); + if (isdigit(chr)) goto next; + if ((chr == '.') && (!had_decimal_dot)) { had_decimal_dot = 1; goto next; } + if (((chr == 'e') || (chr == 'E')) && (!had_e)) { /* 1.2e-5 */ + had_e = 1; + chr = getch(ctx); append(chr, return -1); + if (isdigit(chr)) goto next; + if ((chr == '+') || (chr == '-')) { + chr2 = getch(ctx); + if (isdigit(chr2)) { append(chr2, return -1); goto next; } + gcodeerror(ctx, "invalid numeric: e+ or e- must be followed by a digit"); + return -1; + } + gcodeerror(ctx, "invalid numeric: e must be followed by sign or digit"); + return -1; + } + ungetch(ctx, chr); del_last(); + append('\0', return -1); + lval->num = strtod(ctx->buff, NULL); + + return had_decimal_dot ? T_NUM : T_DEC; +} + + + +int gcodelex_(YYSTYPE *lval, gcode_prg_t *ctx) +{ + int chr; + char tmp[128]; + + restart:; + + if (ctx->in_eof) goto handle_eof; + + /* start of a token: read the next non-space character */ + do { chr = getch(ctx); } while((chr == ' ') || (chr == '\t')); + + ctx->used = 0; + + if (isalpha(chr)) { /* read a code or math function name */ + append(toupper(chr), return -1); + for(;;) { + chr = getch(ctx); + if (!isalpha(chr)) { + ungetch(ctx, chr); + break; + } + append(toupper(chr), return -1); + } + if (ctx->used == 1) { + if (ctx->buff[0] == 'N') + return T_LINENO; + lval->chr = ctx->buff[0]; + return T_CHR; /* single letter code */ + } + append('\0', return -1); /* append a virtual \0 so it's easier to strcmp */ + if (strcmp(ctx->buff, "SIN") == 0) return T_SIN; + else if (strcmp(ctx->buff, "COS") == 0) return T_COS; + else if (strcmp(ctx->buff, "TAN") == 0) return T_TAN; + else if (strcmp(ctx->buff, "ASIN") == 0) return T_ASIN; + else if (strcmp(ctx->buff, "ACOS") == 0) return T_ACOS; + else if (strcmp(ctx->buff, "ATAN") == 0) return T_ATAN; + else if (strcmp(ctx->buff, "ABS") == 0) return T_ABS; + else if (strcmp(ctx->buff, "FIX") == 0) return T_FIX; + else if (strcmp(ctx->buff, "FUP") == 0) return T_FUP; + else if (strcmp(ctx->buff, "EXP") == 0) return T_EXP; + else if (strcmp(ctx->buff, "LN") == 0) return T_LN; + else if (strcmp(ctx->buff, "ROUND") == 0) return T_ROUND; + else if (strcmp(ctx->buff, "SQRT") == 0) return T_SQRT; + else { + gcodeerror(ctx, "Invalid code or math function:"); + gcodeerror(ctx, ctx->buff); + gcodeerror(ctx, "\n"); + return -1; + } + } + else if (isdigit(chr)) { /* read a number */ + append(chr, return -1); + return read_numeric(ctx, lval, 0); + } + else switch(chr) { + case '[': case ']': case '*': case '/': case '+': case '-': case '#': case'=': + return chr; + + case '(': /* read comment */ + for(;;) { + chr = getch(ctx); + if (chr == ')') + goto restart; + if (chr == '\n') { + gcodeerror(ctx, "Newline in comment"); + return -1; + } + if (chr == EOF) { + gcodeerror(ctx, "EOF in comment"); + return -1; + } + } + + case '.': /* number starting with a decimal point */ + append('.', return -1); + return read_numeric(ctx, lval, 1); + break; + + case '\n': + for(;;) { + chr = getch(ctx); + if (!isspace(chr)) { + ungetch(ctx, chr); + return T_NL; + } + } + + case EOF: + handle_eof:; + ctx->in_eof = 1; + return EOF; + + default: + sprintf(tmp, "Invalid character on input: '%c'\n", chr); + gcodeerror(ctx, tmp); + return -1; + } +} + +int gcodelex(YYSTYPE *lval, gcode_prg_t *ctx) +{ + int t = gcodelex_(lval, ctx); +/* printf("* %d\n", t);*/ + return t; +} + Index: tags/1.1.4/src_plugins/import_gcode/gcode_lex.h =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_lex.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_lex.h (revision 818) @@ -0,0 +1,10 @@ +#ifndef GCODE_LEX_H +#define GCODE_LEX_H + +#include "gcode_vm.h" +#include "gcode.tab.h" + +int gcodelex(YYSTYPE *dummy, gcode_prg_t *ctx); +int gcodeerror(gcode_prg_t *ctx, const char *msg); + +#endif Index: tags/1.1.4/src_plugins/import_gcode/gcode_vm.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_vm.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_vm.c (revision 818) @@ -0,0 +1,237 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include + +#include "gcode_vm.h" +#include "gcode.tab.h" + +#ifdef M_PI +# define G_PI M_PI +#else +# define G_PI 3.141592654 +#endif + +#define DEG2RAD (G_PI/180.0) +#define RAD2DEG (180.0/G_PI) + +#define LIST_APPEND(FIRST, LAST, ITEM) \ + do { \ + if (FIRST != NULL) { \ + LAST->next = ITEM; \ + LAST = ITEM; \ + } \ + else \ + FIRST = LAST = ITEM; \ + } while(0) + +static gcode_inst_t *gcode_append_main(gcode_prg_t *ctx) +{ + gcode_inst_t *ex = malloc(sizeof(gcode_inst_t)); + LIST_APPEND(ctx->first, ctx->last, ex); + ex->next = NULL; + ctx->ip++; + return ex; +} + +static gcode_inst_t *gcode_append_2nd(gcode_prg_t *ctx) +{ + gcode_inst_t *ex = malloc(sizeof(gcode_inst_t)); + LIST_APPEND(ctx->first2, ctx->last2, ex); + ex->next = NULL; + ctx->ip2++; + return ex; +} + +void gcode_append(gcode_prg_t *ctx, gcode_i_t inst, double payload) +{ + gcode_inst_t *ex = (ctx->delay == GCP_DELAY_OFF) ? gcode_append_main(ctx) : gcode_append_2nd(ctx); + ex->inst = inst; + ex->payload = payload; +} + +void gcode_delayed(gcode_prg_t *ctx, gcode_delay_t delay) +{ + if ((delay == GCP_DELAY_APPLY) && (ctx->first2 != NULL)) { + LIST_APPEND(ctx->first, ctx->last, ctx->first2); + ctx->last = ctx->last2; + ctx->first2 = ctx->last2 = NULL; + ctx->ip += ctx->ip2; + ctx->ip2 = 0; + } + else + ctx->delay = delay; +} + +void gcode_set_lineno(gcode_prg_t *ctx, int lineno) +{ + ctx->lineno = lineno; + if (ctx->set_lineno != NULL) + ctx->set_lineno(ctx, lineno); +} + +void gcode_dump_inst(const char *prefix, gcode_inst_t *inst) +{ + printf("%s", prefix); + + switch(inst->inst) { + case PUSH_NUM: printf("PUSH_NUM(%f)\n", inst->payload); break; + case ADD: printf("ADD\n"); break; + case SUB: printf("SUB\n"); break; + case MUL: printf("MUL\n"); break; + case DIV: printf("DIV\n"); break; + case ASSIGN: printf("ASSIGN\n"); break; + case PARAM: printf("PARAM(%d)\n", (int)inst->payload); break; + case DO: printf("DO\n\n"); break; + + case T_NUM: printf("NUM(%f)\n", inst->payload); break; + case T_DEC: printf("DEC(%d)\n", (int)inst->payload); break; + case T_LINENO: printf("N(%d)\n", (int)inst->payload); break; + case T_ATAN: printf("ATAN\n"); break; + case T_ACOS: printf("ACOS\n"); break; + case T_ASIN: printf("ASIN\n"); break; + case T_ABS: printf("ABS\n"); break; + case T_COS: printf("COS\n"); break; + case T_SIN: printf("SIN\n"); break; + case T_TAN: printf("TAN\n"); break; + case T_FIX: printf("FIX\n"); break; + case T_FUP: printf("FUP\n"); break; + case T_EXP: printf("EXP\n"); break; + case T_LN: printf("LN\n"); break; + case T_ROUND:printf("ROUND\n"); break; + case T_SQRT: printf("SQRT\n"); break; + case T_MOD: printf("MOD\n"); break; + case T_OR: printf("OR\n"); break; + case T_XOR: printf("XOR\n"); break; + case T_AND: printf("AND\n"); break; + case 'M': + case 'G': + printf("%c%02d\n", inst->inst, (int)inst->payload); break; + default: + if ((inst->inst >= 'A') && (inst->inst <= 'Z')) + printf("%c %f\n", inst->inst, inst->payload); + else + printf("*invalid instruction* %d\n", inst->inst); + } +} + +void gcode_dump_prg(const char *prefix, gcode_prg_t *prg) +{ + gcode_inst_t *i; + for(i = prg->first; i != NULL; i = i->next) + gcode_dump_inst(prefix, i); +} + +static void push(gcode_prg_t *prg, double d) +{ + double *s = vtd0_alloc_append(&prg->stack, 1); + *s = d; +} + +static double pop(gcode_prg_t *prg) +{ + assert(prg->stack.used > 0); + return prg->stack.array[--prg->stack.used]; +} + +int gcode_execute(gcode_prg_t *ctx) +{ + gcode_inst_t *i; + double a, b; + int res, idx, limit = sizeof(ctx->params)/sizeof(ctx->params[0]); + char tmp[256]; + + ctx->lineno = -1; + ctx->ip = 0; + for(i = ctx->first; i != NULL; i = i->next, ctx->ip++) { + switch(i->inst) { + case PUSH_NUM: push(ctx, i->payload); break; + case ADD: a = pop(ctx); b = pop(ctx); push(ctx, a+b); break; + case SUB: a = pop(ctx); b = pop(ctx); push(ctx, a-b); break; + case MUL: a = pop(ctx); b = pop(ctx); push(ctx, a*b); break; + case DIV: a = pop(ctx); b = pop(ctx); push(ctx, a/b); break; + case T_LINENO: ctx->lineno = i->payload; break; + case T_ATAN: a = pop(ctx); b = pop(ctx); push(ctx, atan2(a, b)*RAD2DEG); break; + case T_ACOS: a = pop(ctx); push(ctx, acos(a)*RAD2DEG); break; + case T_ASIN: a = pop(ctx); push(ctx, asin(a)*RAD2DEG); break; + case T_ABS: a = pop(ctx); push(ctx, fabs(a)); break; + case T_COS: a = pop(ctx); push(ctx, cos(a*DEG2RAD)); break; + case T_SIN: a = pop(ctx); push(ctx, sin(a*DEG2RAD)); break; + case T_TAN: a = pop(ctx); push(ctx, tan(a*DEG2RAD)); break; + case T_FIX: a = pop(ctx); push(ctx, floor(a)); break; + case T_FUP: a = pop(ctx); push(ctx, ceil(a)); break; + case T_EXP: a = pop(ctx); push(ctx, exp(a)); break; + case T_LN: a = pop(ctx); push(ctx, log(a)); break; + case T_ROUND: a = pop(ctx); push(ctx, round(a)); break; + case T_SQRT: a = pop(ctx); push(ctx, sqrt(a)); break; + case T_MOD: a = pop(ctx); b = pop(ctx); push(ctx, fmod(a,b)); break; + case T_OR: a = pop(ctx); b = pop(ctx); push(ctx, (a!=0) || (b!=0)); break; + case T_XOR: a = pop(ctx); b = pop(ctx); push(ctx, ((a!=0) || (b!=0)) && ((a==0) || (b==0))); break; + case T_AND: a = pop(ctx); b = pop(ctx); push(ctx, (a!=0) && (b!=0)); break; + case ASSIGN: + a = pop(ctx); b = pop(ctx); + idx = (int)b; + if ((idx < 0) || (idx >= limit)) { + sprintf(tmp, "Error: assignment out of range for parameter %d\n", idx); + ctx->error(ctx, 1, tmp); + return -1; + } + else + ctx->params[idx] = a; + break; + case PARAM: + a = pop(ctx); + idx = (int)a; + if ((idx < 0) || (idx >= limit)) { + sprintf(tmp, "Error: assignment out of range for parameter %d\n", idx); + ctx->error(ctx, 1, tmp); + return -1; + } + else + push(ctx, ctx->params[idx]); + break; + case DO: + res = ctx->execute_code(ctx, i->inst, 0); + if (res != 0) + return res; + break; + default: + if ((i->inst >= 'A') && (i->inst <= 'Z')) { + if (i->payload == -1) + a = pop(ctx); + else + a = i->payload; + res = ctx->execute_code(ctx, i->inst, a); + if (res != 0) + return res; + } + } + } + return 0; +} Index: tags/1.1.4/src_plugins/import_gcode/gcode_vm.h =================================================================== --- tags/1.1.4/src_plugins/import_gcode/gcode_vm.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/gcode_vm.h (revision 818) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef GCODE_VM_H +#define GCODE_VM_H + +#include + +typedef enum { + PUSH_NUM = 1000, + ADD, SUB, MUL, DIV, + ASSIGN, PARAM, DO +} gcode_i_t; + +typedef struct gcode_inst_s gcode_inst_t; + +struct gcode_inst_s { + int inst; /* a letter or a T_ or gcode_i_t */ + double payload; + gcode_inst_t *next; +}; + +typedef enum { + GCP_DELAY_OFF = 0, /* start collecting instructions on the first (main program) list */ + GCP_DELAY_ON, /* start collecting instructions on the 2nd (temporary list) */ + GCP_DELAY_APPLY /* append 2nd list to the main and empty it */ +} gcode_delay_t; + +typedef struct gcode_prg_s gcode_prg_t; +struct gcode_prg_s { + struct { + unsigned laser:1; + } cfg; + + /*** shared ***/ + void (*error)(gcode_prg_t *ctx, int runtime, const char *msg); /* provided by the caller */ + void (*set_lineno)(gcode_prg_t *ctx, int lineno); /* optional: provided by the caller */ + long ip; + int lineno; + + /*** lexer states ***/ + int (*get_char)(gcode_prg_t *ctx); /* provided by the caller */ + int in_eof, pushback, subseq_error; + long line, col, used, alloced; + char *buff; + + /*** compiler states ***/ + gcode_inst_t *first, *last; /* main program */ + gcode_inst_t *first2, *last2; /* temporary storage for assignments */ + gcode_delay_t delay; + long ip2; + + /*** execution states ***/ + int (*execute_code)(gcode_prg_t *ctx, int code, double param); /* provided by the caller; returns 0 on success; code is DO for executing the line */ + double params[5400]; + vtd0_t stack; + unsigned laser_on:1; + + /*** caller's ***/ + void *user_data; + void *exec_data; +}; + + +void gcode_delayed(gcode_prg_t *ctx, gcode_delay_t delay); +void gcode_append(gcode_prg_t *ctx, gcode_i_t inst, double payload); +void gcode_set_lineno(gcode_prg_t *ctx, int lineno); + +void gcode_dump_inst(const char *prefix, gcode_inst_t *inst); +void gcode_dump_prg(const char *prefix, gcode_prg_t *prg); + +int gcodeparse(gcode_prg_t *ctx); +int gcode_execute(gcode_prg_t *ctx); + +#endif Index: tags/1.1.4/src_plugins/import_gcode/import_gcode.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/import_gcode.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/import_gcode.c (revision 818) @@ -0,0 +1,212 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019,2022 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "plug_io.h" +#include "obj_any.h" +#include "conf_core.h" + +#include "gcode_vm.h" +#include "gcode_exec.h" + +#include "import_gcode_conf.h" + +conf_import_gcode_t conf_import_gcode; +static const char io_gcode_cookie[] = "io_gcode"; + +#include "conf_internal.c" + +typedef struct { + htip_t h2l; /* height-to-layer */ + const char *fn; + FILE *fin; + camv_design_t *camv; +} read_ctx_t; + +static int ggetchar(gcode_prg_t *prg) +{ + read_ctx_t *ctx = prg->user_data; + int chr = fgetc(ctx->fin); + return chr; +} + +static void error(gcode_prg_t *ctx, int runtime, const char *msg) +{ + fprintf(stderr, "g-code %s error:", runtime ? "runtime" : "compile"); + if (ctx->lineno >= 0) { + fprintf(stderr, " (in N%d)\n", ctx->lineno); + ctx->lineno = -1; + } + fprintf(stderr, "%s\n", msg); +} + +static camv_layer_t *get_layer(gcode_prg_t *prg, double height_) +{ + read_ctx_t *ctx = prg->user_data; + long height = height_ * 1000; + camv_layer_t *ly; + + if ((height_ < -1000) || (height_ > +1000)) + error(prg, 1, "Error: board too thick"); + + ly = htip_get(&ctx->h2l, height); + if (ly == NULL) { + const char *sh; + ly = camv_layer_new(); + ly->name = rnd_strdup_printf("%s/%dum", ctx->fn, height); + sh = strrchr(ctx->fn, '/'); + if (sh == NULL) + sh = ctx->fn; + else + sh++; + ly->short_name = rnd_strdup_printf("%s/%dum", sh, height); + camv_layer_invent_color(ctx->camv, ly); + camv_layer_append_to_design(ctx->camv, ly); + htip_set(&ctx->h2l, height, ly); + } + + return ly; +} + +static void travel(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2) +{ + printf("TRAVEL %f;%f;%f -> %f;%f;%f\n", x1, y1, z1, x2, y2, z2); +} + +static void linear(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2) +{ + read_ctx_t *ctx = prg->user_data; + int in_place = (x1 == x2) && (y1 == y2); + camv_layer_t *ly; + camv_any_obj_t *o; + + if (z1 != z2) { + if (!in_place) + error(prg, 1, "Error: only horizontal or vertical move allowed"); + return; + } + + ly = get_layer(prg, z1); + o = (camv_any_obj_t *)camv_line_new(); + o->line.x1 = RND_MM_TO_COORD(x1); o->line.y1 = RND_MM_TO_COORD(y1); + o->line.x2 = RND_MM_TO_COORD(x2); o->line.y2 = RND_MM_TO_COORD(y2); +TODO("implement tools"); + o->line.thick = 1; + camv_obj_add_to_layer(ly, o); + + printf("LINEAR %f;%f;%f -> %f;%f;%f\n", x1, y1, z1, x2, y2, z2); +} + +static gcode_execute_op_t ops = {travel, linear}; + +static int camv_gcode_load(camv_design_t *camv, const char *fn, FILE *fin) +{ + gcode_prg_t prg; + read_ctx_t ctx; + + memset(&prg, 0, sizeof(prg)); + prg.user_data = &ctx; + ctx.camv = camv; + ctx.fn = fn; + ctx.fin = fin; + htip_init(&ctx.h2l, longhash, longkeyeq); + + prg.get_char = ggetchar; + prg.error = error; + if (gcodeparse(&prg) != 0) + return 1; + + prg.cfg.laser = conf_import_gcode.plugins.import_gcode.laser; + gcode_execute_init(&prg, &ops); + gcode_execute(&prg); + gcode_execute_uninit(&prg); + + htip_uninit(&ctx.h2l); + return 0; +} + +static int camv_gcode_test_load(camv_design_t *camv, const char *fn, FILE *f) +{ + char *line, line_[1024]; + int bad = 0; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + while(isspace(*line)) line++; + if (*line == '(') + continue; + if ((strstr(line, "G20") != NULL) || (strstr(line, "G21") != NULL)) + return 1; + bad++; + if (bad > 16) + return 0; + } + return 0; +} + + +static camv_io_t io_gcode = { + "gcode", 80, + camv_gcode_test_load, + camv_gcode_load, + NULL +}; + + +int pplg_check_ver_import_gcode(int ver_needed) { return 0; } + +void pplg_uninit_import_gcode(void) +{ + rnd_conf_plug_unreg("plugins/import_gcode/", import_gcode_conf_internal, io_gcode_cookie); + camv_io_unreg(&io_gcode); +} + +int pplg_init_import_gcode(void) +{ + camv_io_reg(&io_gcode); + + rnd_conf_plug_reg(conf_import_gcode, import_gcode_conf_internal, io_gcode_cookie); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_import_gcode, field,isarray,type_name,cpath,cname,desc,flags); +#include "import_gcode_conf_fields.h" + + return 0; +} Index: tags/1.1.4/src_plugins/import_gcode/import_gcode.conf =================================================================== --- tags/1.1.4/src_plugins/import_gcode/import_gcode.conf (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/import_gcode.conf (revision 818) @@ -0,0 +1,9 @@ +li:camv-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:import_gcode { + laser = 0; + } + } + } +} Index: tags/1.1.4/src_plugins/import_gcode/import_gcode.pup =================================================================== --- tags/1.1.4/src_plugins/import_gcode/import_gcode.pup (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/import_gcode.pup (revision 818) @@ -0,0 +1,9 @@ +$class import +$short gcode CNC programs +$long Load board g-code CNC programs +$package import +$state works +$fmt-native no +$fmt-feature-r g-code CNC program +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/import_gcode/import_gcode_conf.h =================================================================== --- tags/1.1.4/src_plugins/import_gcode/import_gcode_conf.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/import_gcode_conf.h (revision 818) @@ -0,0 +1,8 @@ +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN laser; /* Import g-code assuming laser plotting: M3/M4 is laser on, M5 is laser off */ + } import_gcode; + } plugins; +} conf_import_gcode_t; + Index: tags/1.1.4/src_plugins/import_gcode/main.c =================================================================== --- tags/1.1.4/src_plugins/import_gcode/main.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gcode/main.c (revision 818) @@ -0,0 +1,67 @@ +#include +#include "gcode_vm.h" +#include "gcode_exec.h" + +gcode_prg_t prg; + +static int ggetchar(gcode_prg_t *ctx) +{ + FILE *f = ctx->user_data; + int chr = fgetc(f); + return chr; +} + +static int execute_code(gcode_prg_t *ctx, int code, double param) +{ + if (code == DO) + printf("-- do\n"); + else + printf("CALL %c %f\n", code, param); + return 0; +} + +static void error(gcode_prg_t *ctx, int runtime, const char *msg) +{ + fprintf(stderr, "g-code %s error:", runtime ? "runtime" : "compile"); + if (ctx->lineno >= 0) { + fprintf(stderr, " (in N%d)\n", ctx->lineno); + ctx->lineno = -1; + } + fprintf(stderr, "%s\n", msg); +} + +static void travel(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2) +{ + printf("TRAVEL %f;%f;%f -> %f;%f;%f\n", x1, y1, z1, x2, y2, z2); +} + +static void linear(gcode_prg_t *prg, double x1, double y1, double z1, double x2, double y2, double z2) +{ + printf("LINEAR %f;%f;%f -> %f;%f;%f\n", x1, y1, z1, x2, y2, z2); +} + +static gcode_execute_op_t ops = {travel, linear}; + +int main(int argc, char *argv[]) +{ + const char *fn = "a.gcode"; + FILE *fin = fopen(fn, "r"); + + prg.get_char = ggetchar; + prg.user_data = fin; +/* prg.execute_code = execute_code;*/ + prg.error = error; + if (gcodeparse(&prg) != 0) + return 1; + fclose(fin); + + printf("*** DUMP:\n"); + gcode_dump_prg("", &prg); + + printf("*** EXEC:\n"); + gcode_execute_init(&prg, &ops); + gcode_execute(&prg); + gcode_execute_uninit(&prg); + + return 0; +} Index: tags/1.1.4/src_plugins/import_gerb/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/import_gerb/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/Plug.tmpasm (revision 818) @@ -0,0 +1,14 @@ +put /local/rnd/mod {import_gerb} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/import_gerb/gerb2camv.o + $(PLUGDIR)/import_gerb/geparse.o + $(PLUGDIR)/import_gerb/gedraw.o + $(PLUGDIR)/import_gerb/gexpr.o + $(PLUGDIR)/import_gerb/gex.tab.o +@] + +switch /local/module/import_gerb/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/import_gerb/doc/cmd_support.txt =================================================================== --- tags/1.1.4/src_plugins/import_gerb/doc/cmd_support.txt (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/doc/cmd_support.txt (revision 818) @@ -0,0 +1,38 @@ +Commands supported (lower case represent arguments) + +D01 draw (poly mode: draw contour, ignore aperture) +D02 move +D03 flash (poly mode: error) +Dn (where n > 10) select aperture +G01 interpolation: linear +G02 interpolation: CW circular +G03 interpolation: CCW circular +G04 comment +G36 poly mode: filled polygon mode on +G37 poly mode: filled polygon mode off +G54Dn (where n > 10) select aperture +G70 set unit to INCH +G71 set unit to MM +G74 set single quadrant mode (arc) +G75 set multi quadrant mode (arc) +G90 switch to absolute coords +G91 switch to relative coords +Xc move X, absolute +Yc move Y, absolute +Ic move X, relative (arc) +Jc move Y, relative (arc) +%MOIN set unit to INCH +%MOMM set unit to MM +%FS..XcYc set coordinate format; supports 'L'/'T' and 'A'/'I' +%ADD add aperture +%LN layer name +%LP (sub)layer polarity +%SR step-and-repeat + +Not supported yet (TODO): + AM: (aperture macro) + +Not supported (need example): + G10 magnified linear interpolation + G11 magnified linear interpolation + G12 magnified linear interpolation Index: tags/1.1.4/src_plugins/import_gerb/doc/config.txt =================================================================== --- tags/1.1.4/src_plugins/import_gerb/doc/config.txt (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/doc/config.txt (revision 818) @@ -0,0 +1,5 @@ +draw_aper_hole [bool] ? + Aperture holes clearly need to be flashed, but it's not clear whether they + need to be drawn in D01/D02 or not. If true, draw holes in D01/D02, if false + use them only for flashing. + Index: tags/1.1.4/src_plugins/import_gerb/doc/links =================================================================== --- tags/1.1.4/src_plugins/import_gerb/doc/links (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/doc/links (revision 818) @@ -0,0 +1,2 @@ +http://pcbdesign-now.blogspot.com/2012/06/gerber-for-beginners.html +https://www.artwork.com/gerber/appl2.htm Index: tags/1.1.4/src_plugins/import_gerb/expr/Makefile =================================================================== --- tags/1.1.4/src_plugins/import_gerb/expr/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/expr/Makefile (revision 818) @@ -0,0 +1,15 @@ +TRUNK=../../../../trunk + +include $(TRUNK)/Makefile.conf + +CFLAGS = -DRND_PCB_COMPAT -Wall -g -I.. -I$(TRUNK)/src -I$(TRUNK) -I$(TRUNK)/src_3rd $(CFLAGS_LIBRND) +LDLIBS = -lrnd-3rd + +main: main.o ../gex.tab.o ../gexpr.o + +main.o: main.c ../gex.tab.h ../gexpr.h + +../gex.tab.c ../gex.tab.h: ../gex.y ../gexpr.h + cd ../../../src && make gerbyacc + + Index: tags/1.1.4/src_plugins/import_gerb/expr/main.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/expr/main.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/expr/main.c (revision 818) @@ -0,0 +1,54 @@ +#include +#include +#include "gexpr.h" + +extern int gexparse(ge_expr_prglist_t *ctx); + +int gexlex(YYSTYPE *lval, ge_expr_prglist_t *ctx_) +{ + char tmp[128], *end; + int ti, c = getchar(); + switch(c) { + case '(': case ')': case '+': case '-': case 'x': case '/': return c; + case '$': + c = getchar(); + for(ti = 0; isdigit(c) && (ti < sizeof(tmp)-1); c = getchar(),ti++) + tmp[ti] = c; + tmp[ti] = '\0'; + ungetc(c, stdin); + lval->idx = atoi(tmp); + return T_PARAM; + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '.': + for(ti = 0; (isdigit(c) || (c == '.')) && (ti < sizeof(tmp)-1); c = getchar(),ti++) + tmp[ti] = c; + tmp[ti] = '\0'; + ungetc(c, stdin); + lval->num = strtod(tmp, &end); + return T_NUM; + case '\n': return 0; + } + return c; +} + +int gexerror(ge_expr_prglist_t *ctx_, const char *msg) +{ + printf("ERROR: %s\n", msg); + return 0; +} + +int main() +{ + ge_expr_prglist_t lst; + vtd0_t params; + double res; + + memset(&lst, 0, sizeof(ge_expr_prglist_t)); + gexparse(&lst); + + vtd0_init(¶ms); + printf("eval: %d\n", gex_eval(lst.first, ¶ms, &res)); + printf("res: %f\n", res); + return 0; +} + Index: tags/1.1.4/src_plugins/import_gerb/gedraw.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gedraw.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gedraw.c (revision 818) @@ -0,0 +1,107 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#define GVT_DONT_UNDEF +#include "gedraw.h" +#include +#undef GVT_DONT_UNDEF + +#include "geparse.h" + +gedraw_inst_t *gedraw_alloc(gedraw_ctx_t *ctx, long line, long col) +{ + gedraw_inst_t *i; + i = vtgd_alloc_append(&ctx->code, 1); + i->line = line; + i->col = col; + return i; +} + +void gedraw_dump_inst(FILE *f, gedraw_ctx_t *ctx, gedraw_inst_t *i) +{ + fprintf(f, "[%04ld %04ld.%02ld] ", (long)(i - ctx->code.array), (long)i->line, (long)i->col); + switch(i->cmd) { + case GEC_invalid: fprintf(f, "invalid\n"); break; + case GEC_MACRO_DEF: fprintf(f, "MACRO_DEF %s\n", i->data.aper.data.macro.name); break; + case GEC_APER_DEF: fprintf(f, "APER_DEF %ld\n", i->data.aper.id); break; + case GEC_APER_SEL: fprintf(f, "APER_SEL %ld\n", i->data.id); break; + case GEC_DRAW: fprintf(f, "DRAW\n"); break; + case GEC_MOVE: fprintf(f, "MOVE\n"); break; + case GEC_FLASH: fprintf(f, "FLASH\n"); break; + case GEC_DO: fprintf(f, "DO\n"); break; + case GEC_SET_X: fprintf(f, "X %f mm\n", i->data.coord / 1000000.0); break; + case GEC_SET_Y: fprintf(f, "Y %f mm\n", i->data.coord / 1000000.0); break; + case GEC_SET_I: fprintf(f, "I %f mm\n", i->data.coord / 1000000.0); break; + case GEC_SET_J: fprintf(f, "J %f mm\n", i->data.coord / 1000000.0); break; + case GEC_SET_RELCRD: fprintf(f, "RELCRD %s\n", i->data.on ? "on" : "off"); break; + case GEC_SET_POLCLR: fprintf(f, "POLCLR %s\n", i->data.on ? "clear" : "draw"); break; + case GEC_SET_POLY: fprintf(f, "POLY %s\n", i->data.on ? "on" : "off"); break; + case GEC_SET_RELAT: fprintf(f, "RELAT %s\n", i->data.on ? "on" : "off"); break; + case GEC_SET_INTERP: + switch(i->data.interp) { + case GEI_LIN: fprintf(f, "INTERP linear\n"); break; + case GEI_CW: fprintf(f, "INTERP cw\n"); break; + case GEI_CCW: fprintf(f, "INTERP ccw\n"); break; + } + break; + case GEC_SET_QUADR: + switch(i->data.quadr) { + case GEQ_INVALID:fprintf(f, "QUADR !!!invalid!!!\n"); break; + case GEQ_SINGLE: fprintf(f, "QUADR single\n"); break; + case GEQ_MULTI: fprintf(f, "QUADR multi\n"); break; + } + break; + case GEC_STEPREP: + if (i->data.steprep.end) + fprintf(f, "STEPREP end\n"); + else + fprintf(f, "STEPREP %d;%d %f;%f\n", i->data.steprep.x, i->data.steprep.y, i->data.steprep.i / 1000000.0, i->data.steprep.j / 1000000.0); + break; + } +} + +void gedraw_dump_code(FILE *f, gedraw_ctx_t *ctx) +{ + gedraw_inst_t *i; + size_t n; + for(n = 0, i = ctx->code.array; n < ctx->code.used; n++,i++) + gedraw_dump_inst(f, ctx, i); +} + +void gedraw_free(gedraw_ctx_t *ctx) +{ + gedraw_inst_t *i; + size_t n; + for(n = 0, i = ctx->code.array; n < ctx->code.used; n++,i++) + if (i->cmd == GEC_APER_DEF) + vtd0_uninit(&i->data.aper.data.macro.param); + + vtgd_uninit(&ctx->code); +} Index: tags/1.1.4/src_plugins/import_gerb/gedraw.h =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gedraw.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gedraw.h (revision 818) @@ -0,0 +1,206 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef GEDRAW_H +#define GEDRAW_H + +#include +#include +#include +#include +#include + +#include +#include +#include "gexpr.h" + +typedef rnd_coord_t ge_coord_t; /* nanometer */ +typedef rnd_angle_t ge_angle_t; /* degree */ + +typedef enum { + GEP_NEXT, /* all fine, read the next char */ + GEP_END, /* all fine, end of stream */ + GEP_ERROR /* stop reading */ +} ge_parse_res_t; + +typedef enum { + GEU_NONE = 0, + GEU_INCH, + GEU_MM +} ge_unit_t; + +typedef enum { + GEA_CIRC, + GEA_RECT, + GEA_OBLONG, + GEA_POLY, + GEA_MACRO +} ge_aper_shape_t; + +typedef enum { + GEMO_CIRC = 1, + GEMO_POLY = 4, + GEMO_REGPOLY = 5, + GEMO_MOIRE = 6, + GEMO_THERM = 7, + GEMO_LINE_XY = 20, + GEMO_LINE_WH = 21, + + GEMO_SET /* this one doesn't have a numeric code but it is really just an instruction; operant[0] is target param idx, operand[1] is the expression */ +} ge_macro_op_t; + +typedef struct ge_macro_line_s ge_macro_line_t; +struct ge_macro_line_s { + ge_macro_op_t op; /* operator: type of primitive */ + vtp0_t operand; /* each entry is the first item of a linked list of a (ge_expr_prg_t *) */ + int idx; /* only for GEMO_SET: target index, so it doesn't need to be converted to an expression */ + ge_macro_line_t *next; +}; + +typedef struct ge_aper_macro_s { + ge_macro_line_t *line1; /* frist line of a singly linked list of macro lines to execute in order */ + ge_macro_line_t *last; /* last line of a singly linked list of macro lines (for cheap append) */ + int argc; + double *argv; +} ge_aper_macro_t; + +typedef struct { + ge_aper_shape_t shape; /* macro aper doesn't have it */ + ge_coord_t hole; /* macro aper doesn't have it */ + union { + struct { + ge_coord_t dia; + } circ; + struct { + ge_coord_t xs, ys; + } rect; + struct { + ge_coord_t xs, ys; + } oblong; + struct { + ge_coord_t dia, corners; + ge_angle_t rot; + } poly; + struct { + const char *name; /* allocated in the macro hash (as key) */ + const ge_aper_macro_t *am; /* allocated in the macro hash (as value) */ + vtd0_t param; /* only for aperture def */ + } macro; + } data; + long id; + void *cached; /* optional: generated/cached prototype, specific ot the drawing code */ +} ge_aper_t; + +typedef enum { /* interpolation mode */ + GEI_LIN = 0, /* linear (default) */ + GEI_CW, /* circular, clock-wise */ + GEI_CCW /* circular, counter-clock-wise */ +} ge_interp_t; + +typedef enum { /* circular interpolation quadrants */ + GEQ_INVALID = 0, /* default: invalid, yields error */ + GEQ_SINGLE, /* span must be less than 90 deg */ + GEQ_MULTI /* span may be more than 90 deg */ +} ge_quadr_t; + +typedef struct { + int x, y; /* x and y repeat */ + ge_coord_t i, j; + int end; /* coords are invalid */ +} ge_steprep_t; + +typedef enum { /* field to use */ + GEC_invalid = 0, + GEC_MACRO_DEF, /* -> aper */ + GEC_APER_DEF, /* -> aper */ + GEC_APER_SEL, /* -> id */ + GEC_DRAW, /* n/a */ + GEC_MOVE, /* n/a */ + GEC_FLASH, /* n/a */ + GEC_DO, /* n/a */ + GEC_STEPREP, /* -> steprep */ + GEC_SET_X, /* -> coord */ + GEC_SET_Y, /* -> coord */ + GEC_SET_I, /* -> coord */ + GEC_SET_J, /* -> coord */ + GEC_SET_RELCRD, /* -> on (relative coordinates) */ + GEC_SET_POLCLR, /* -> on (polarity; when on, clear instead of draw (negative polarity)) */ + GEC_SET_POLY, /* -> on */ + GEC_SET_RELAT, /* -> on */ + GEC_SET_INTERP, /* -> interp */ + GEC_SET_QUADR /* -> quadr */ +} gedraw_cmd_t; + +typedef struct { + gedraw_cmd_t cmd; + union { + ge_aper_t aper; + ge_coord_t coord; + int on; + long id; + ge_interp_t interp; + ge_quadr_t quadr; + ge_steprep_t steprep; + } data; + + long line, col; /* location in the input file for error messages */ +} gedraw_inst_t; + +#define GVT(x) vtgd_ ## x +#define GVT_ELEM_TYPE gedraw_inst_t +#define GVT_SIZE_TYPE size_t +#define GVT_DOUBLING_THRS 4096 +#define GVT_START_SIZE 32 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + +typedef struct { + ge_unit_t aper_unit; /* unit used for macro apertures */ + rnd_coord_t acceptable_error; /* depends on coord precision determined by the parser */ + unsigned aper_inited:1; /* aperutre hash initialized */ + unsigned poly_closed:1; /* set by the contour append code if current polyline is closed at the moment (curos is at starting point) */ + ge_interp_t interp; + ge_quadr_t quadr; + htip_t aper; + vtgd_t code; + vtc0_t contour;/* polygon drawing state */ + rnd_coord_t ox, oy; /* rendering origin - 0;0 for the main drawing, modified by SR */ +} gedraw_ctx_t; + +gedraw_inst_t *gedraw_alloc(gedraw_ctx_t *ctx, long line, long col); + +void gedraw_dump_inst(FILE *f, gedraw_ctx_t *ctx, gedraw_inst_t *i); +void gedraw_dump_code(FILE *f, gedraw_ctx_t *ctx); + +void gedraw_free(gedraw_ctx_t *ctx); + + +#endif Index: tags/1.1.4/src_plugins/import_gerb/gedump.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gedump.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gedump.c (revision 818) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include +#include "geparse.h" + +/*** hidlib emulation (glue) ***/ +#undef rnd_message +#undef rnd_message_level +enum rnd_message_level {RND_MSG_DUMMY}; +void rnd_message(enum rnd_message_level ignored, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +/* Implementation idea borrowed from an old gcc (GPL'd) */ +double rnd_round(double x) +{ + double t; + +/* We should check for inf here, but inf is not in C89; if we'd have isinf(), + we'd have round() as well and we wouldn't be here at all. */ + + if (x >= 0.0) { + t = ceil(x); + if (t - x > 0.5) + t -= 1.0; + return t; + } + + t = ceil(-x); + if ((t + x) > 0.5) + t -= 1.0; + return -t; +} + + +/*** parser ***/ +static int ge_getchar(geparse_ctx_t *ctx) +{ + return fgetc(stdin); +} + + +int main() +{ + geparse_ctx_t ctx; + ge_parse_res_t res; + + memset(&ctx, 0, sizeof(ctx)); + ctx.get_char = ge_getchar; + while((res = geparse(&ctx)) == GEP_NEXT) ; + if (res == GEP_ERROR) { + fprintf(stderr, "parse error at %ld:%ld: %s\n", ctx.line, ctx.col, ctx.errmsg); + geparse_free(&ctx); + return 1; + } + + gedraw_dump_code(stderr, &ctx.draw); + + geparse_free(&ctx); + return 0; +} Index: tags/1.1.4/src_plugins/import_gerb/geparse.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/geparse.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/geparse.c (revision 818) @@ -0,0 +1,1041 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "geparse.h" +#include "gedraw.h" +#include "gexpr.h" +#include "gex.tab.h" +#include + +#include + +/* valid polygon aperture corners */ +#define POLY_MIN_CORNERS 3 +#define POLY_MAX_CORNERS 16 + +/* valid coordinates can't take more than this number of characters in a string */ +#define MAX_COORD_STRLEN 16 + +#define COMPILE(ctx, cmd_, field, arg) \ + do { \ + gedraw_inst_t *inst; \ + inst = gedraw_alloc(&((ctx)->draw), (ctx)->line, (ctx)->col); \ + inst->cmd = (cmd_); \ + inst->data.field = arg; \ + } while(0) + +#define COMPILE0(ctx, cmd_) \ + do { \ + gedraw_inst_t *inst; \ + inst = gedraw_alloc(&((ctx)->draw), (ctx)->line, (ctx)->col); \ + inst->cmd = (cmd_); \ + } while(0) + +#define READ_(_ctx_, _res_, allow_eof) \ + do { \ + for(;;) { \ + int _step_ = 0; \ + if (_ctx_->ungetc != 0) { \ + _res_ = _ctx_->ungetc; \ + _ctx_->ungetc = 0; \ + } \ + else { \ + _step_ = 1; \ + _res_ = ctx->get_char(ctx); \ + if ((_res_ < 32) && (_res_ != '\n') && (_res_ != '\r') && (_res_ != '\t')) { \ + ctx->errmsg = "Invalid character (low binary)"; \ + return GEP_ERROR; \ + } \ + else if (_res_ >= 127) { \ + ctx->errmsg = "Invalid character (high binary)"; \ + return GEP_ERROR; \ + } \ + } \ + if (_step_) \ + ctx->col++; \ + if (_res_ == EOF) { \ + if (!allow_eof) { \ + ctx->errmsg = "Invalid command (first character is EOF)"; \ + return GEP_ERROR; \ + } \ + break; \ + } \ + else if (_res_ == '\n') { \ + if (_step_) { \ + ctx->col = 0; \ + ctx->line++; \ + } \ + } \ + else if (_res_ == '\r') { \ + } \ + else \ + break; \ + } \ + } while(0) + +#define UNGETC(_ctx_, _c_) \ + do { \ + if (_ctx_->ungetc != 0) { \ + ctx->errmsg = "Internal error: multiple UNGETC calls"; \ + return GEP_ERROR; \ + } \ + _ctx_->ungetc = _c_; \ + } while(0) + +#define READ(_ctx_, _res_) READ_(_ctx_, _res_, 0) + +#define READ_NUM(_ctx_, _res_) \ + do { \ + int __sign__ = 1, __digc__, __dig__; \ + _res_ = 0; \ + for(__digc__ = 0;;__digc__++) { \ + if (__digc__ > 10) { \ + _ctx_->errmsg = "Number too long"; \ + return GEP_ERROR; \ + } \ + READ(_ctx_, __dig__); \ + if (__dig__ == '-') { \ + if (__digc__ == 0) __sign__ = -1; \ + else break;\ + } \ + else if (__dig__ == '+') { \ + if (__digc__ == 0) __sign__ = +1; \ + else break;\ + } \ + else if (isdigit(__dig__)) \ + _res_ = _res_ * 10 + __dig__ - '0'; \ + else \ + break; \ + } \ + if (__sign__ < 0) \ + _res_ = -_res_; \ + UNGETC(_ctx_, __dig__); \ + } while(0) + +/* read decimal into a char * buffer _res_; _len_inout_ is the maximum + length as input and actual length as output */ +#define READ_DEC_(_ctx_, _buf_, _len_inout_, _permit_decpt_) \ + do { \ + int __i__, __c__, __got_pt__ = 0; \ + for(__i__ = 0;;__i__++) { \ + if (__i__ >= _len_inout_-1) { \ + _ctx_->errmsg = "Number too long"; \ + return GEP_ERROR; \ + } \ + READ(_ctx_, __c__); \ + _buf_[__i__] = __c__; \ + if (__c__ == '-') { \ + if (__i__ != 0) \ + break;\ + } \ + else if (__c__ == '+') { \ + if (__i__ != 0) \ + break;\ + } \ + else if (_permit_decpt_ && (__c__ == '.')) { \ + if (__got_pt__ == 0) __got_pt__ = 1; \ + else break;\ + } \ + else if (!isdigit(__c__)) \ + break; \ + } \ + _buf_[__i__] = '\0'; \ + _len_inout_ = __i__; \ + UNGETC(_ctx_, __c__); \ + } while(0) + +/* parse decimal into double _res_ */ +#define READ_DEC(_ctx_, _res_) \ + do { \ + char __buf__[16]; \ + int __len__ = sizeof(__buf__); \ + READ_DEC_(_ctx_, __buf__, __len__, 1); \ + _res_ = strtod(__buf__, NULL); \ + } while(0) + +#define READ_COORD(_ctx_, _res_) \ + do { \ + char __buf__[3*MAX_COORD_STRLEN], *__start__ = __buf__+MAX_COORD_STRLEN; \ + int __len__ = MAX_COORD_STRLEN, __need__ = _ctx_->cfmt_int + _ctx_->cfmt_fra, __save__, __has_sign__, __sign__; \ + long __int__; \ + double __fra__; \ + READ_DEC_(_ctx_, __start__, __len__, 0); \ + if (__need__ > 25) { \ + _ctx_->errmsg = "Coordinate format too long"; \ + return GEP_ERROR; \ + } \ + if ((_ctx_->cfmt_int < 1) || (_ctx_->cfmt_fra < 1)) { \ + _ctx_->errmsg = "Coordinate format too short"; \ + return GEP_ERROR; \ + } \ + __has_sign__ = (*__start__ == '-') || (*__start__ == '+'); \ + __sign__ = *__start__; \ + if (__len__ - __has_sign__ > __need__) { \ + _ctx_->errmsg = "Coordinate longer than format permits"; \ + return GEP_ERROR; \ + } \ + if (_ctx_->trailing_zero) { \ + while(__len__ < __need__) { \ + __buf__[__len__] = '0'; \ + __len__++; \ + } \ + __buf__[__len__] = '\0'; \ + } \ + else { \ + if (__has_sign__) \ + __start__++;\ + while(__len__ - __has_sign__ < __need__) { \ + __start__--; \ + *__start__ = '0'; \ + __len__++; \ + } \ + if (__has_sign__) {\ + __start__--; \ + *__start__ = __sign__; \ + } \ + } \ + __save__ = __start__[_ctx_->cfmt_int - 1 + __has_sign__]; \ + __start__[_ctx_->cfmt_int - 1 + __has_sign__] = '.'; \ + __fra__ = strtod(__start__ + _ctx_->cfmt_int + __has_sign__ - 1, NULL); \ + __start__[_ctx_->cfmt_int - 1 + __has_sign__] = __save__; \ + __start__[_ctx_->cfmt_int + __has_sign__] = '\0'; \ + __int__ = strtol(__start__, NULL, 10); \ + _res_ = ge_intfra_to_coord(_ctx_, __int__, __fra__, __has_sign__ && (__sign__ == '-')); \ + } while(0) + +#define READ_ANGLE(_ctx_, _res_) READ_DEC(_ctx_, _res_) + +#define READ_COORD_DEC(_ctx_, _res_) \ + do { \ + double __tmp__; \ + READ_DEC(_ctx_, __tmp__); \ + _res_ = ge_double_to_coord(_ctx_, __tmp__); \ + } while(0) + + +#define READ_UPCASE(_ctx_, _res_) \ + do { \ + READ(_ctx_, _res_); \ + if (!isupper(_res_)) { \ + _ctx_->errmsg = "Unexpected uppercase alpha character"; \ + return GEP_ERROR; \ + } \ + } while(0) + +#define READ_CMDEND(_ctx_) \ + do { \ + for(;;) { \ + int __c__; \ + READ(_ctx_, __c__); \ + if (__c__ == '*') \ + break;\ + _ctx_->errmsg = "Unexpected character while looking for command terminator ('*')"; \ + return GEP_ERROR; \ + } \ + } while(0) + +#define READ_LONGEND(_ctx_) \ + do { \ + for(;;) { \ + int __c__; \ + READ(_ctx_, __c__); \ + if (__c__ == '%') \ + break;\ + _ctx_->errmsg = "Unexpected character while looking for long command terminator ('%')"; \ + return GEP_ERROR; \ + } \ + } while(0) + +#define READ_TILL_CMDEND(_ctx_) \ + do { \ + for(;;) { \ + int __c__; \ + READ(_ctx_, __c__); \ + if (__c__ == '*') \ + break;\ + } \ + } while(0) + +#define READ_APERTURE(_ctx_, _aid_, _allow_empty_) \ + do { \ + int __c__; \ + READ(_ctx_, __c__); \ + if (__c__ != '*') { \ + if (__c__ != 'D') { \ + _ctx_->errmsg = "Expected 'D' for aperture ID"; \ + return GEP_ERROR; \ + } \ + READ_NUM(_ctx_, _aid_); \ + } \ + else { \ + if (!_allow_empty_) { \ + _ctx_->errmsg = "Expected 'D' for aperture ID - empty aperture not supported in this context"; \ + return GEP_ERROR; \ + } \ + else \ + _aid_ = -42; \ + } \ + } while(0) + +/* Append a macro name into a gds string, utnil endchr or '*' (endchr is not consumed) */ +#define READ_NAME_GDS(_ctx_, dst, endchr) \ +do { \ + for(;;) { \ + READ(ctx, c); \ + if ((c == endchr) || (c == '*')) {\ + UNGETC(_ctx_, c); \ + break; \ + } \ + gds_append(&name, c); \ + } \ +} while(0) + +static double ge_round(double x) +{ + return rnd_round(x); +} + +ge_coord_t ge_double_to_coord(geparse_ctx_t *ctx, double d) +{ + switch(ctx->unit) { + case GEU_INCH: + return ge_round(d * 25400000.0); + case GEU_MM: + default: + return ge_round(d * 1000000.0); + } +} + +ge_coord_t ge_intfra_to_coord(geparse_ctx_t *ctx, long int_part, double fra_part, int is_neg) +{ + ge_coord_t c; + + if (int_part < 0) + int_part = -int_part; + c = ge_double_to_coord(ctx, (double)int_part + fra_part); /* lazy approach, slow but still accurate enough because of the magnitude of i and f */ + return is_neg ? -c : c; +} + +static ge_parse_res_t geparse_aperture_spec_shaped(geparse_ctx_t *ctx, long aid, int shape) +{ + int c; + gedraw_inst_t *inst = gedraw_alloc(&ctx->draw, ctx->line, ctx->col); + + inst->data.aper.id = aid; + switch(shape) { + case 'C': + inst->data.aper.shape = GEA_CIRC; + READ_COORD_DEC(ctx, inst->data.aper.data.circ.dia); + READ(ctx, c); + if (c == '*') /* it seems a few arguments at the end are optional; especially rotation for '1' (circle) may be missing */ + break; + if (c != 'X') { + ctx->errmsg = "unexpected character in circle aperture def"; + return GEP_ERROR; + } + READ_COORD_DEC(ctx, inst->data.aper.hole); + + READ(ctx, c); + if (c == '*') + break; + ctx->errmsg = "unexpected character at the end of a circle aperture def"; + return GEP_ERROR; + + case 'R': + inst->data.aper.shape = GEA_RECT; + rect_cheat:; + READ_COORD_DEC(ctx, inst->data.aper.data.rect.xs); + READ(ctx, c); + if (c != 'X') { + ctx->errmsg = "unexpected character in rectangle aperture def after x-size"; + return GEP_ERROR; + } + READ_COORD_DEC(ctx, inst->data.aper.data.rect.ys); + READ(ctx, c); + if (c == '*') + break; + if (c != 'X') { + ctx->errmsg = "unexpected character in rectangle aperture def"; + return GEP_ERROR; + } + READ_COORD_DEC(ctx, inst->data.aper.hole); + READ(ctx, c); + if (c == '*') + break; + ctx->errmsg = "unexpected character at the end of a circle aperture def"; + return GEP_ERROR; + + + case 'O': + inst->data.aper.shape = GEA_OBLONG; + goto rect_cheat; /* we can do this as long as the struct for the two are the same */ + break; + + case 'P': + inst->data.aper.shape = GEA_POLY; + READ_COORD_DEC(ctx, inst->data.aper.data.poly.dia); + READ(ctx, c); + if (c != 'X') { + ctx->errmsg = "unexpected character in polygon aperture def after diameter"; + return GEP_ERROR; + } + READ_NUM(ctx, inst->data.aper.data.poly.corners); + READ(ctx, c); + if (c == '*') + goto poly_fin; + if (c != 'X') { + ctx->errmsg = "unexpected character in polygon aperture def (at angle)"; + return GEP_ERROR; + } + READ_ANGLE(ctx, inst->data.aper.data.poly.rot); + READ(ctx, c); + if (c == '*') + goto poly_fin; + if (c != 'X') { + ctx->errmsg = "unexpected character in polygon aperture def (at hole)"; + return GEP_ERROR; + } + READ_COORD_DEC(ctx, inst->data.aper.hole); + READ(ctx, c); + + poly_fin:; + if (inst->data.aper.data.poly.corners < POLY_MIN_CORNERS) { + ctx->errmsg = "invalid polygon aperture: too few corners"; + return GEP_ERROR; + } + if (inst->data.aper.data.poly.corners > POLY_MAX_CORNERS) { + ctx->errmsg = "invalid polygon aperture: too many corners"; + return GEP_ERROR; + } + break; + default: + ctx->errmsg = "unsupported aperture shape (character)"; + return GEP_ERROR; + } + READ_LONGEND(ctx); + inst->cmd = GEC_APER_DEF; + return GEP_NEXT; +} + +/*** expression parsing ***/ +int gexerror(ge_expr_prglist_t *ctx_, const char *msg) +{ + geparse_ctx_t *ctx = ctx_->parent; + ctx->errmsg = msg; + return -1; +} + +int gexlex(YYSTYPE *lval, ge_expr_prglist_t *ctx_) +{ + geparse_ctx_t *ctx = ctx_->parent; + int c; + + READ(ctx, c); + switch(c) { + case ',': + case '%': + case '*': + UNGETC(ctx, c); + return 0; + case '$': + READ_NUM(ctx, lval->idx); + return T_PARAM; + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '.': + UNGETC(ctx, c); + READ_DEC(ctx, lval->num); + return T_NUM; + } + return c; +} + +TODO("switch over from byacc to byaccic and have a .h"); +int gexparse(ge_expr_prglist_t *lst); + +static int geparse_macro_expr(geparse_ctx_t *ctx, ge_expr_prg_t **res) { + int r; + ge_expr_prglist_t lst; + + lst.first = lst.last = NULL; + lst.parent = ctx; + + r = gexparse(&lst); + if (r == 0) + *res = lst.first; + else + *res = NULL; + + return 0; +} + +static ge_macro_line_t *macro_append(geparse_ctx_t *ctx, ge_aper_macro_t *am) +{ + ge_macro_line_t *line = calloc(sizeof(ge_macro_line_t), 1); + if (am->last != NULL) { + am->last->next = line; + am->last = line; + } + else + am->line1 = am->last = line; + + return line; +} + +static int geparse_macro_aperture_line(geparse_ctx_t *ctx, ge_aper_macro_t *am, int code, int argc) +{ + int c, a; + ge_macro_line_t *line = macro_append(ctx, am); + + line->op = code; + + for(a = 0; a < argc; a++) { + ge_expr_prg_t *e; + READ(ctx, c); + if (c == '*') + return 0; + if ((a < argc-1) && (c != ',')) { + ctx->errmsg = "macro aperture: missing comma (not enough parameters?)"; + return -1; + } + geparse_macro_expr(ctx, &e); + vtp0_append(&line->operand, e); + if ((a == argc-1) && (c == '*')) + return 0; + } + READ_CMDEND(ctx); + return 0; +} + +static int geparse_macro_aperture_poly(geparse_ctx_t *ctx, ge_aper_macro_t *am, int code) +{ + int c, a, numpts; + double er; + ge_expr_prg_t *e; + vtd0_t allzero; + ge_macro_line_t *line = macro_append(ctx, am); + + line->op = code; + + for(a = 0; a < 2; a++) { + READ(ctx, c); + if (c != ',') { + ctx->errmsg = "macro aperture: missing comma (not enough parameters?)"; + return -1; + } + geparse_macro_expr(ctx, &e); + vtp0_append(&line->operand, e); + } + + memset(&allzero, 0, sizeof(allzero)); + if (gex_eval(e, &allzero, &er) != 0) { + ctx->errmsg = "macro aperture: failed to evaluate number of polygon points"; + return -1; + } + numpts = rnd_round(er); + + for(a = 0; a < numpts*2+3; a++) { + READ(ctx, c); + if (c != ',') { + ctx->errmsg = "macro aperture: missing comma (not enough points?)"; + return -1; + } + geparse_macro_expr(ctx, &e); + vtp0_append(&line->operand, e); + } + + READ_CMDEND(ctx); + return 0; +} + +static int geparse_macro_aperture_set(geparse_ctx_t *ctx, ge_aper_macro_t *am) +{ + ge_expr_prg_t *e; + int idx, c; + double d; + ge_macro_line_t *line = macro_append(ctx, am); + + READ_NUM(ctx, idx); + READ(ctx, c); + if (c != '=') + return -1; + line->op = GEMO_SET; + line->idx = idx; + geparse_macro_expr(ctx, &e); + vtp0_append(&line->operand, e); + READ_CMDEND(ctx); + return 0; +} + +static ge_parse_res_t geparse_macro_aperture(geparse_ctx_t *ctx) +{ + gedraw_inst_t *inst; + ge_aper_macro_t *am; + int c = 0; + gds_t name; + + /* read the name and check for dups */ + gds_init(&name); + READ_NAME_GDS(ctx, &name, '*'); + READ(ctx, c); /* remvoe the '*' */ + if (htsp_has(ctx->macros, name.array)) { + gds_uninit(&name); + ctx->errmsg = "macro aperture: duplicate macro name"; + return GEP_ERROR; + } + + am = calloc(sizeof(ge_aper_macro_t), 1); + inst = gedraw_alloc(&ctx->draw, ctx->line, ctx->col); + inst->data.aper.data.macro.name = name.array; + inst->cmd = GEC_MACRO_DEF; + inst->data.aper.shape = GEA_MACRO; + inst->data.aper.data.macro.am = am; + + htsp_set(ctx->macros, name.array, am); + /* do _not_ call gds_uninit(&name): alloction is now owned by the hash table */ + + for(;;) { + int code, lineres; + READ(ctx, c); + switch(c) { + case '$': + if (geparse_macro_aperture_set(ctx, am) != 0) + return GEP_ERROR; + continue; + case '%': + return GEP_NEXT; /* long command termination */ + default: + UNGETC(ctx, c); /* would be a numeric code */ + } + READ_NUM(ctx, code); + switch(code) { + case 0: /* comment */ + READ_TILL_CMDEND(ctx); + lineres = 0; + break; + case GEMO_CIRC: lineres = geparse_macro_aperture_line(ctx, am, code, 5); break; + case GEMO_POLY: lineres = geparse_macro_aperture_poly(ctx, am, code); break; + case GEMO_REGPOLY: lineres = geparse_macro_aperture_line(ctx, am, code, 6); break; + case GEMO_MOIRE: lineres = geparse_macro_aperture_line(ctx, am, code, 9); break; + case GEMO_THERM: lineres = geparse_macro_aperture_line(ctx, am, code, 6); break; + case GEMO_LINE_XY: lineres = geparse_macro_aperture_line(ctx, am, code, 7); break; + case GEMO_LINE_WH: lineres = geparse_macro_aperture_line(ctx, am, code, 6); break; + default: + ctx->errmsg = "macro aperture: unknown primtive code"; + return GEP_ERROR; + } + if (lineres != 0) + return GEP_ERROR; + } +} + +#define CMD(c1, c2) ((((unsigned int)c1)<<8) | (((unsigned int)c2))) + +static ge_parse_res_t geparse_aperture_add(geparse_ctx_t *ctx) +{ + int c1, c2, c; + long aid; + + READ_APERTURE(ctx, aid, 1); + if (aid == -42) { + READ_LONGEND(ctx); + return GEP_NEXT; + } + if (aid < 10) { + ctx->errmsg = "invalid aperture ID: must be at least 10"; + return GEP_ERROR; + } + READ(ctx, c1); + READ(ctx, c2); + if (c2 != ',') { /* named macro */ + char sep; + gds_t name; + htsp_entry_t *he; + ge_aper_macro_t *am; + gedraw_inst_t *inst; + + gds_init(&name); + gds_append(&name, c1); + gds_append(&name, c2); + READ_NAME_GDS(ctx, &name, ','); + + he = htsp_getentry(ctx->macros, name.array); + if (he == NULL) { + ctx->errmsg = "named aperture not found"; + return GEP_ERROR; + } + am = he->value; + gds_uninit(&name); + + inst = gedraw_alloc(&ctx->draw, ctx->line, ctx->col); + READ(ctx, sep); + while(sep != '*') { + double d; + READ_DEC(ctx, d); + vtd0_append(&inst->data.aper.data.macro.param, d); + READ(ctx, sep); + if ((sep != 'X') && (sep != '*')) { + vtd0_uninit(&inst->data.aper.data.macro.param); + ctx->errmsg = "aperture macro: invalid parameter separator: expected X or *"; + return GEP_ERROR; + } + } + + inst->cmd = GEC_APER_DEF; + inst->data.aper.shape = GEA_MACRO; + inst->data.aper.id = aid; + inst->data.aper.data.macro.name = he->key; + inst->data.aper.data.macro.am = am; + + READ_LONGEND(ctx); + return GEP_NEXT; + } + + /* simple, non-macro aperture */ + return geparse_aperture_spec_shaped(ctx, aid, c1); +} + +static ge_parse_res_t geparse_set_unit(geparse_ctx_t *ctx) +{ + int c1, c2; + + READ_UPCASE(ctx, c1); + READ_UPCASE(ctx, c2); + switch(CMD(c1, c2)) { + case CMD('I', 'N'): + ctx->unit = GEU_INCH; + READ_CMDEND(ctx); + break; + case CMD('M', 'M'): + ctx->unit = GEU_MM; + READ_CMDEND(ctx); + break; + default: + ctx->errmsg = "invalid unit for %%MO"; + return GEP_ERROR; + } + + READ_LONGEND(ctx); + return GEP_NEXT; +} + +static ge_parse_res_t geparse_steprep(geparse_ctx_t *ctx) +{ + int c; + + gedraw_inst_t *inst = gedraw_alloc(&ctx->draw, ctx->line, ctx->col); + inst->cmd = GEC_STEPREP; + READ(ctx, c); + switch(c) { + case 'X': + inst->data.steprep.end = 0; + READ_NUM(ctx, inst->data.steprep.x); + READ(ctx, c); if (c != 'Y') goto steprep_err; + READ_NUM(ctx, inst->data.steprep.y); + READ(ctx, c); if (c != 'I') goto steprep_err; + READ_COORD_DEC(ctx, inst->data.steprep.i); + READ(ctx, c); if (c != 'J') goto steprep_err; + READ_COORD_DEC(ctx, inst->data.steprep.j); + READ(ctx, c); if (c != '*') goto steprep_err; + break; + case '*': + inst->data.steprep.end = 1; + break; + default: + ctx->errmsg = "unsupported SR parameter: must be empty or must start with X"; + return GEP_ERROR; + } + READ_LONGEND(ctx); + return GEP_NEXT; + + steprep_err:; + ctx->errmsg = "invalid %SR argument format"; + return GEP_ERROR; +} + +static ge_parse_res_t geparse_coordfmt(geparse_ctx_t *ctx) +{ + int c, x1, y1, x2, y2; + + READ(ctx, c); + switch(c) { + case 'L': ctx->trailing_zero = 0; break; + case 'T': ctx->trailing_zero = 1; break; + default: + ctx->errmsg = "unsupported coord format: %FS zero padding character must be 'L' or 'T'"; + return GEP_ERROR; + } + READ(ctx, c); + switch(c) { + case 'A': COMPILE(ctx, GEC_SET_RELCRD, on, 0); break; + case 'I': COMPILE(ctx, GEC_SET_RELCRD, on, 1); break; + default: + ctx->errmsg = "unsupported coord format: %FS coord reference character should be 'A' or 'I'"; + return GEP_ERROR; + } + READ(ctx, c); if (c != 'X') goto bad_cmd; + READ(ctx, x1); if (!isdigit(x1)) goto bad_num; + READ(ctx, x2); if (!isdigit(x2)) goto bad_num; + READ(ctx, c); if (c != 'Y') goto bad_cmd; + READ(ctx, y1); if (!isdigit(y1)) goto bad_num; + READ(ctx, y2); if (!isdigit(y2)) goto bad_num; + READ_CMDEND(ctx); + if ((x1 != y1) || (x2 != y2)) { + ctx->errmsg = "unsupported coord format: %FS X and Y should be the same"; + return GEP_ERROR; + } + ctx->cfmt_int = x1 - '0'; + ctx->cfmt_fra = x2 - '0'; + + READ_LONGEND(ctx); + return GEP_NEXT; + + bad_num:; + ctx->errmsg = "expected digit"; + return GEP_ERROR; + + bad_cmd:; + ctx->errmsg = "missing X or Y in coord format spec"; + return GEP_ERROR; +} + +ge_parse_res_t geparse_long_cmd(geparse_ctx_t *ctx) +{ + int c1, c2, c; + + READ_UPCASE(ctx, c1); + READ_UPCASE(ctx, c2); + switch(CMD(c1, c2)) { + case CMD('M', 'O'): + return geparse_set_unit(ctx); + + case CMD('S', 'R'): + return geparse_steprep(ctx); + + case CMD('I', 'P'): /* image polarity - pos or neg */ + READ(ctx, c); + switch(c) { + case 'P': /* positive is the default setup, no need to do anything */ break; + case 'N': rnd_message(RND_MSG_WARNING, "IPNEG: negative image polarity is not yet supported:\nthe image will be displayed in inverse.\n"); break; + default: rnd_message(RND_MSG_WARNING, "Invalid IP arg, assuming POS\n"); + } + READ_TILL_CMDEND(ctx); + break; + + case CMD('L', 'P'): + READ(ctx, c); + switch(c) { + case 'C': COMPILE(ctx, GEC_SET_POLCLR, on, 1); break; + case 'D': COMPILE(ctx, GEC_SET_POLCLR, on, 0); break; + } + READ_CMDEND(ctx); + COMPILE0(ctx, GEC_DO); + break; + + case CMD('F', 'S'): /* coord format */ + return geparse_coordfmt(ctx); + + case CMD('A', 'D'): /* add aperture */ + return geparse_aperture_add(ctx); + + case CMD('A', 'M'): /* add macro aperture, up to and including the terminator % */ + return geparse_macro_aperture(ctx); + + case CMD('L', 'N'): /* layer name? -> ignore */ + READ_TILL_CMDEND(ctx); + break; + + case CMD('I', 'N'): /* design name? -> ignore */ + READ_TILL_CMDEND(ctx); + break; + + /* these are just overly fancy comments really -> ignore */ + case CMD('T', 'F'): + case CMD('T', 'A'): + case CMD('T', 'D'): + case CMD('T', 'O'): + READ_TILL_CMDEND(ctx); + break; + + /* offset and scale factor -> ignore for now */ + case CMD('O', 'F'): + case CMD('S', 'F'): + READ_TILL_CMDEND(ctx); + break; + + + default: + ctx->errmsg = "unrecognized long command"; + return GEP_ERROR; + } + + READ_LONGEND(ctx); + return GEP_NEXT; +} +#undef CMD + +#define CMD(chr, code) ((((unsigned int)chr)<<8)+code) +ge_parse_res_t geparse_short_cmd(geparse_ctx_t *ctx, int cmd) +{ + ge_coord_t crd; + long code; + int c; + + + switch(cmd) { /* single char short commands */ + case '*': COMPILE0(ctx, GEC_DO); return GEP_NEXT; + case 'X': READ_COORD(ctx, crd); COMPILE(ctx, GEC_SET_X, coord, crd); return GEP_NEXT; + case 'Y': READ_COORD(ctx, crd); COMPILE(ctx, GEC_SET_Y, coord, crd); return GEP_NEXT; + case 'I': READ_COORD(ctx, crd); COMPILE(ctx, GEC_SET_I, coord, crd); return GEP_NEXT; + case 'J': READ_COORD(ctx, crd); COMPILE(ctx, GEC_SET_J, coord, crd); return GEP_NEXT; + case 'D': + select_aper:; + READ_NUM(ctx, code); + if (code < 10) + goto d_cmd; /* these are not apertures but commands; code is already parsed */ + READ_CMDEND(ctx); + COMPILE(ctx, GEC_APER_SEL, id, code); + return GEP_NEXT; + } + + READ_NUM(ctx, code); + d_cmd:; + code += ((unsigned int)cmd) << 8; + switch(code) { + case CMD('G', 01): COMPILE(ctx, GEC_SET_INTERP, interp, GEI_LIN); return GEP_NEXT; + case CMD('G', 02): COMPILE(ctx, GEC_SET_INTERP, interp, GEI_CW); return GEP_NEXT; + case CMD('G', 03): COMPILE(ctx, GEC_SET_INTERP, interp, GEI_CCW); return GEP_NEXT; + case CMD('G', 04): READ_TILL_CMDEND(ctx); return GEP_NEXT; + case CMD('G', 36): READ_CMDEND(ctx); COMPILE(ctx, GEC_SET_POLY, on, 1); return GEP_NEXT; + case CMD('G', 37): READ_CMDEND(ctx); COMPILE(ctx, GEC_SET_POLY, on, 0); return GEP_NEXT; + case CMD('G', 54): + READ(ctx, c); + if (c != 'D') { + ctx->errmsg = "G54 requires a 'D'\n"; + return GEP_ERROR; + } + goto select_aper; + case CMD('G', 70): READ_CMDEND(ctx); ctx->unit = GEU_INCH; return GEP_NEXT; + case CMD('G', 71): READ_CMDEND(ctx); ctx->unit = GEU_MM; return GEP_NEXT; + case CMD('G', 74): READ_CMDEND(ctx); COMPILE(ctx, GEC_SET_QUADR, interp, GEQ_SINGLE); return GEP_NEXT; + case CMD('G', 75): READ_CMDEND(ctx); COMPILE(ctx, GEC_SET_QUADR, interp, GEQ_MULTI); return GEP_NEXT; + case CMD('G', 90): COMPILE(ctx, GEC_SET_RELCRD, on, 0); return GEP_NEXT; + case CMD('G', 91): COMPILE(ctx, GEC_SET_RELCRD, on, 1); return GEP_NEXT; + case CMD('D', 01): COMPILE0(ctx, GEC_DRAW); return GEP_NEXT; + case CMD('D', 02): COMPILE0(ctx, GEC_MOVE); return GEP_NEXT; + case CMD('D', 03): COMPILE0(ctx, GEC_FLASH); return GEP_NEXT; + case CMD('M', 02): READ_CMDEND(ctx); ctx->at_end = 1; return GEP_END; + } + ctx->errmsg = "unknown short command code\n"; + return GEP_ERROR; +} +#undef CMD + + +static ge_parse_res_t geparse_(geparse_ctx_t *ctx) +{ + if (ctx->at_end) + return GEP_END; + if (ctx->line == 0) + ctx->line = 1; + for(;;) { + int c; + + READ(ctx, c); + switch(c) { + case EOF: + if (ctx->cmd_cnt == 0) { + ctx->errmsg = "EOF before the first command"; + return GEP_ERROR; + } + return GEP_END; + case '\n': + case '\r': + break; + case '%': + ctx->cmd_cnt++; + return geparse_long_cmd(ctx); + case 'D': + case 'G': + case 'M': + case 'X': + case 'Y': + case 'I': + case 'J': + case '*': + ctx->cmd_cnt++; + return geparse_short_cmd(ctx, c); + default: + ctx->errmsg = "Invalid command (first character)"; + return GEP_ERROR; + } + } +} + +ge_parse_res_t geparse(geparse_ctx_t *ctx) +{ + if (ctx->macros == NULL) + ctx->macros = htsp_alloc(strhash, strkeyeq); + return geparse_(ctx); +} + +static void geparse_free_macro_aper(ge_aper_macro_t *am) +{ + ge_macro_line_t *l, *next; + for(l = am->line1; l != NULL; l = next) { + int a; + next = l->next; + for(a = 0; a < l->operand.used; a++) + gex_free_prg(l->operand.array[a]); + free(l->operand.array); + free(l); + } + free(am->argv); + free(am); +} + +void geparse_free(geparse_ctx_t *ctx) +{ + gedraw_free(&ctx->draw); + if (ctx->macros != NULL) { + htsp_entry_t *e; + for(e = htsp_first(ctx->macros); e != NULL; e = htsp_next(ctx->macros, e)) { + free(e->key); /* name */ + geparse_free_macro_aper(e->value); + } + htsp_free(ctx->macros); + } +} + Index: tags/1.1.4/src_plugins/import_gerb/geparse.h =================================================================== --- tags/1.1.4/src_plugins/import_gerb/geparse.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/geparse.h (revision 818) @@ -0,0 +1,59 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "gedraw.h" + +#include + +typedef struct geparse_ctx_s geparse_ctx_t; + +struct geparse_ctx_s { + /* public: parser state */ + long line, col, cmd_cnt; + const char *errmsg; + + /* public: caller provided functions */ + int (*get_char)(geparse_ctx_t *ctx); /* read the next character from the stream */ + + /* public: data used only by the caller */ + void *user_data; + + /* private: parser state */ + ge_unit_t unit; + int cfmt_int, cfmt_fra; /* coordinate format: integer and fraction digits */ + int ungetc; + unsigned trailing_zero:1; /* coords are padded with trailing zeros */ + unsigned at_end:1; + + /* private: draw program */ + gedraw_ctx_t draw; + htsp_t *macros; /* both key and values pointing into the bytecode */ +}; + + +ge_parse_res_t geparse(geparse_ctx_t *ctx); +void geparse_free(geparse_ctx_t *ctx); + Index: tags/1.1.4/src_plugins/import_gerb/gerb2camv.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gerb2camv.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gerb2camv.c (revision 818) @@ -0,0 +1,1251 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "data.h" +#include "plug_io.h" +#include "obj_any.h" + +#include "geparse.h" +#include "gedraw.h" + +/*** low level draw ***/ + +/* assumes dst is zero sized */ +static void pline2camv(camv_poly_t *dst, rnd_pline_t *src) +{ + rnd_pline_t *l; + rnd_vnode_t *v; + long n; + + n = 0; + for(l = src; l != NULL; l = l->next) { + v = l->head; +#ifdef DONT_TRUST_COUNT + do { + n++; + v = v->next; + } while(v != &l->head); +#else + n += l->Count; +#endif +/* printf("l cont=%d n=%ld\n", l->Count, n);*/ + } + + + camv_poly_allocpts(dst, n); + n = 0; + for(l = src; l != NULL; l = l->next) { + v = l->head; + do { + dst->x[n] = v->point[0]; + dst->y[n] = v->point[1]; + n++; + v = v->next; + } while(v != l->head); + } +} + +static void emit_build(rnd_pline_t *pl, void *ud) +{ + camv_grp_t *dst = ud; + camv_poly_t *opoly = (camv_poly_t *)&dst->objs[dst->len]; + camv_poly_init(opoly); + pline2camv(opoly, pl); + dst->len++; +} + +/* Returns a polygon or a group of polygons, free's src*/ +static camv_any_obj_t *polyarea2camv(rnd_polyarea_t *src) +{ + rnd_pline_t *l; + long holes = 0, islands = 0; + rnd_polyarea_t *pa; + + pa = src; + do { + for(l = pa->contours->next; l != NULL; l = l->next) holes++; + islands++; + pa = pa->f; + } while(pa != src); + + if (holes > 0) { /* has holes, dice and return a group of objects */ + camv_grp_t *grp = camv_grp_new(); + grp->len = 0; + grp->objs = calloc(sizeof(camv_any_obj_t), (holes+2)*2); + rnd_polyarea_no_holes_dicer(src, 0, 0, 0, 0, emit_build, grp); /* handles islands */ + return (camv_any_obj_t *)grp; + } + else { + if (islands != 1) { /* multiple islands, no holes: need to create a group of camv polygons */ + long i = 0; + camv_grp_t *grp = camv_grp_new(); + + grp->len = islands; + grp->objs = malloc(sizeof(camv_any_obj_t) * grp->len); + pa = src; + do { + camv_poly_t *dst = &grp->objs[i].poly; + camv_poly_init(dst); + pline2camv(dst, pa->contours); + i++; + pa = pa->f; + } while(pa != src); + rnd_polyarea_free(&src); + return (camv_any_obj_t *)grp; + } + else { /* single island, no holes: return a sinlge camv poly */ + camv_poly_t *dst = camv_poly_new(); + pline2camv(dst, src->contours); + rnd_polyarea_free(&src); + return (camv_any_obj_t *)dst; + } + } +} + +/* Convert an oblong aperture into a camv polygon around 0;0 */ +static camv_any_obj_t *aper_oblong2poly(ge_aper_t *aper, double rot) +{ + rnd_coord_t xs = aper->data.oblong.xs, ys = aper->data.oblong.ys, xh, yh; + rnd_polyarea_t *pa, *ph, *ptmp; + camv_any_obj_t *o; + int n; + + TODO("figure if we need rotation"); + + /* real thin oblong is sometimes made to be 0 in size that would be a + self intersecting poly; fix that up */ + if (xs < 2) xs = 2; + if (ys < 2) ys = 2; + + xh = rnd_round((double)xs / 2.0); + yh = rnd_round((double)ys / 2.0); + if (xh > yh) + pa = rnd_poly_from_line(-xh+yh, 0, +xh-yh, 0, ys, 0); + else + pa = rnd_poly_from_line(0, -yh+xh, 0, +yh-xh, xs, 0); + + /* subtract the hole if there's one */ + if (aper->hole > 0) { + ph = rnd_poly_from_circle(0, 0, aper->hole/2); + rnd_polyarea_boolean_free(pa, ph, &ptmp, RND_PBO_SUB); + pa = ptmp; + } + + o = polyarea2camv(pa); + return o; +} + +/* Convert a regular polygon with no hole aperture into a camv polygon around 0;0 */ +static camv_any_obj_t *aper_poly2poly_nohole(ge_aper_t *aper, double rot) +{ + camv_any_obj_t *o; + double r, a, as; + int n; + + o = (camv_any_obj_t *)camv_poly_new(); + camv_poly_allocpts(&o->poly, aper->data.poly.corners); + as = (360.0 / (double)aper->data.poly.corners) / RND_RAD_TO_DEG; + r = (double)aper->data.poly.dia / 2.0; + for(n = 0, a = (rot + aper->data.poly.rot) / RND_RAD_TO_DEG; n < aper->data.poly.corners; n++,a+=as) { + o->poly.x[n] = rnd_round(r * cos(a)); + o->poly.y[n] = rnd_round(r * sin(a)); + } + return o; +} + +static rnd_polyarea_t *pa_regpoly(rnd_coord_t cx, rnd_coord_t cy, rnd_cardinal_t corners, rnd_coord_t dia, double rot) +{ + rnd_pline_t *contour; + rnd_vector_t v; + double r, a, as; + int n; + + as = (360.0 / (double)corners) / RND_RAD_TO_DEG; + r = (double)dia / 2.0; + + for(n = 0, a = rot / RND_RAD_TO_DEG; n < corners; n++, a+=as) { + v[0] = cx + rnd_round(r * cos(a)); + v[1] = cy + rnd_round(r * sin(a)); + if (n == 0) + contour = rnd_poly_contour_new(v); + else + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + + return rnd_poly_from_contour_autoinv(contour); +} + +/* Convert a regular polygon with hole aperture into a camv polygon around 0;0 */ +static camv_any_obj_t *aper_poly2poly_hole(ge_aper_t *aper, double rot) +{ + rnd_polyarea_t *ps, *ph, *pres; + + ps = pa_regpoly(0, 0, aper->data.poly.corners, aper->data.poly.dia, rot + aper->data.poly.rot); + ph = rnd_poly_from_circle(0, 0, aper->hole/2); + rnd_polyarea_boolean_free(ps, ph, &pres, RND_PBO_SUB); + + return polyarea2camv(pres); +} + +/* idx is counted from 1 for code clarity */ +static int param_eval_int(const ge_macro_line_t *l, int paridx, vtd0_t *param) +{ + double res; + ge_expr_prg_t **prg = (ge_expr_prg_t **)vtp0_get((vtp0_t *)&l->operand, paridx-1, 0); + if (prg == NULL) return 0; + gex_eval(*prg, param, &res); + return rnd_round(res); +} + +/* idx is counted from 1 for code clarity */ +static double param_eval_dbl(const ge_macro_line_t *l, int paridx, vtd0_t *param) +{ + double res; + ge_expr_prg_t **prg = (ge_expr_prg_t **)vtp0_get((vtp0_t *)&l->operand, paridx-1, 0); + if (prg == NULL) return 0; + gex_eval(*prg, param, &res); + return res; +} + +/* idx is counted from 1 for code clarity */ +static rnd_coord_t param_eval_crd(gedraw_ctx_t *ctx, const ge_macro_line_t *l, int paridx, vtd0_t *param) +{ + double res; + ge_expr_prg_t **prg = (ge_expr_prg_t **)vtp0_get((vtp0_t *)&l->operand, paridx-1, 0); + if (prg == NULL) return 0; + gex_eval(*prg, param, &res); + + if (ctx->aper_unit == GEU_INCH) + res *= 25.4; + /* else we are in mm already */ + + return (rnd_coord_t)RND_MM_TO_COORD(res); +} + +/* merge pb into dst (pol=0: clear, pol=1: draw) */ +static void macro_line_render_merge(rnd_polyarea_t **dst, rnd_polyarea_t *pb, int pol) +{ + rnd_polyarea_t *pa = *dst; + + if (pa == NULL) { + if ((pb == NULL) || (!pol)) + return; + *dst = pb; + } + else { + *dst = NULL; + rnd_polyarea_boolean_free(pa, pb, dst, pol ? RND_PBO_UNITE : RND_PBO_SUB); + } +} + +static rnd_polyarea_t *pa_rect(rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t x3, rnd_coord_t y3, rnd_coord_t x4, rnd_coord_t y4) +{ + rnd_vector_t v; + rnd_pline_t *pl; + + v[0] = x1; + v[1] = y1; + pl = rnd_poly_contour_new(v); + + v[0] = x2; + v[1] = y2; + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = x3; + v[1] = y3; + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = x4; + v[1] = y4; + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + return rnd_poly_from_contour_autoinv(pl); +} + +static rnd_polyarea_t *pa_rect_rot(rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t x3, rnd_coord_t y3, rnd_coord_t x4, rnd_coord_t y4, double cs, double sn) +{ + rnd_vector_t v; + rnd_pline_t *pl; + + v[0] = x1; + v[1] = y1; + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + pl = rnd_poly_contour_new(v); + + v[0] = x2; + v[1] = y2; + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = x3; + v[1] = y3; + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = x4; + v[1] = y4; + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + return rnd_poly_from_contour_autoinv(pl); +} + + + +static rnd_polyarea_t *pa_ring(rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t d_outer, rnd_coord_t d_inner) +{ + rnd_polyarea_t *pbig, *psmall, *pout; + + pbig = rnd_poly_from_circle(cx, cy, d_outer/2); + if (d_inner < 100) + return pbig; + psmall = rnd_poly_from_circle(cx, cy, d_inner/2); + rnd_polyarea_boolean_free(pbig, psmall, &pout, RND_PBO_SUB); + return pout; +} + +/* Render a single line (primitive) of a macro into an accumulating polyarea dst */ +static int macro_line_render(gedraw_ctx_t *ctx, rnd_polyarea_t **dst, const ge_macro_line_t *l, vtd0_t *param, double rot) +{ + int pol, corners, n, maxrng; + rnd_coord_t x, y, d, th, x1, y1, x2, y2, od, id, rth, chth, chd, gap, w, h; + double r, vx, vy, nx, ny, len, cs, sn; + rnd_polyarea_t *pb, *pc, *pd; + rnd_vector_t v; + rnd_pline_t *contour; + + switch(l->op) { + case GEMO_CIRC: + pol = param_eval_int(l, 1, param); + d = param_eval_crd(ctx, l, 2, param); + x = param_eval_crd(ctx, l, 3, param); + y = param_eval_crd(ctx, l, 4, param); + r = param_eval_dbl(l, 5, param) + rot; + if (r != 0) + rnd_rotate(&x, &y, 0, 0, cos(-r / RND_RAD_TO_DEG), sin(-r / RND_RAD_TO_DEG)); + pb = rnd_poly_from_circle(x, y, d/2); + macro_line_render_merge(dst, pb, pol); + return 0; + case GEMO_POLY: + pol = param_eval_int(l, 1, param); + corners = param_eval_int(l, 2, param); + r = param_eval_dbl(l, l->operand.used, param) + rot; + cs = cos(-r / RND_RAD_TO_DEG); + sn = sin(-r / RND_RAD_TO_DEG); + v[0] = param_eval_crd(ctx, l, 3, param); + v[1] = param_eval_crd(ctx, l, 4, param); + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + contour = rnd_poly_contour_new(v); + for(n = 1; n < corners; n++) { + v[0] = param_eval_crd(ctx, l, n*2+3, param); + v[1] = param_eval_crd(ctx, l, n*2+4, param); + rnd_rotate(&v[0], &v[1], 0, 0, cs, sn); + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + pb = rnd_poly_from_contour_autoinv(contour); + macro_line_render_merge(dst, pb, pol); + return 0; + case GEMO_REGPOLY: + pol = param_eval_int(l, 1, param); + corners = param_eval_int(l, 2, param); + x = param_eval_crd(ctx, l, 3, param); + y = param_eval_crd(ctx, l, 4, param); + d = param_eval_crd(ctx, l, 5, param); + r = param_eval_dbl(l, 6, param) + rot; + if (r != 0) + rnd_rotate(&x, &y, 0, 0, cos(-r / RND_RAD_TO_DEG), sin(-r / RND_RAD_TO_DEG)); + pb = pa_regpoly(x, y, corners, d, r); + macro_line_render_merge(dst, pb, pol); + return 0; + case GEMO_MOIRE: + x = x1 = param_eval_crd(ctx, l, 1, param); + y = y1 = param_eval_crd(ctx, l, 2, param); + od = param_eval_crd(ctx, l, 3, param); + rth = param_eval_crd(ctx, l, 4, param); + gap = param_eval_crd(ctx, l, 5, param); + maxrng = param_eval_int(l, 6, param); + chth = param_eval_crd(ctx, l, 7, param); + chd = param_eval_crd(ctx, l, 8, param); + r = param_eval_dbl(l, 9, param) + rot; + cs = cos(-r / RND_RAD_TO_DEG); + sn = sin(-r / RND_RAD_TO_DEG); + if (r != 0) { + rnd_rotate(&x1, &y1, 0, 0, cs, sn); + if ((x != 0) || (y != 0)) + rnd_message(RND_MSG_WARNING, "gerb: some gerber viewers (e.g. gerbv) won't render correctly rotated aperture macro primitive Moire when center is not 0;0\n"); + } + + /* crosshair */ + chth /= 2; + chd /= 2; + pb = pa_rect_rot(x-chd, y-chth, x+chd, y-chth, x+chd, y+chth, x-chd, y+chth, cs, sn); /* horizontal */ + pc = pa_rect_rot(x-chth, y-chd, x+chth, y-chd, x+chth, y+chd, x-chth, y+chd, cs, sn); /* vertical */ + rnd_polyarea_boolean_free(pb, pc, &pd, RND_PBO_UNITE); + + /* accumulate rings in pd */ + for(n = 0; (n < maxrng) && (od > 100); od -= gap*2 + rth*2, n++) { + pb = pa_ring(x1, y1, od, od-rth*2); + pc = pd; + pd = NULL; + rnd_polyarea_boolean_free(pb, pc, &pd, RND_PBO_UNITE); + } + + macro_line_render_merge(dst, pd, 1); + return 0; + case GEMO_THERM: + x = x1 = param_eval_crd(ctx, l, 1, param); + y = y1 = param_eval_crd(ctx, l, 2, param); + od = param_eval_crd(ctx, l, 3, param); + id = param_eval_crd(ctx, l, 4, param); + th = param_eval_crd(ctx, l, 5, param); + r = param_eval_dbl(l, 6, param) + rot; + + cs = cos(-r / RND_RAD_TO_DEG); + sn = sin(-r / RND_RAD_TO_DEG); + if (r != 0) { + rnd_rotate(&x1, &y1, 0, 0, cs, sn); + if ((x != 0) || (y != 0)) + rnd_message(RND_MSG_WARNING, "gerb: some gerber viewers (e.g. gerbv) won't render correctly rotated aperture macro primitive therm when center is not 0;0\n"); + } + pb = pa_ring(x1, y1, od, id); + + th /= 2; + pc = pa_rect_rot(x-od, y-th, x+od, y-th, x+od, y+th, x-od, y+th, cs, sn); /* horizontal */ + rnd_polyarea_boolean_free(pb, pc, &pd, RND_PBO_SUB); + + pc = pa_rect_rot(x-th, y-od, x+th, y-od, x+th, y+od, x-th, y+od, cs, sn); /* vertical */ + rnd_polyarea_boolean_free(pd, pc, &pb, RND_PBO_SUB); + + macro_line_render_merge(dst, pb, 1); + return 0; + case GEMO_LINE_XY: + pol = param_eval_int(l, 1, param); + th = param_eval_crd(ctx, l, 2, param); + x1 = param_eval_crd(ctx, l, 3, param); + y1 = param_eval_crd(ctx, l, 4, param); + x2 = param_eval_crd(ctx, l, 5, param); + y2 = param_eval_crd(ctx, l, 6, param); + r = param_eval_dbl(l, 7, param) + rot; + + line_xy:; + if (r != 0) { + r = -r; + rnd_rotate(&x1, &y1, 0, 0, cos(r / RND_RAD_TO_DEG), sin(r / RND_RAD_TO_DEG)); + rnd_rotate(&x2, &y2, 0, 0, cos(r / RND_RAD_TO_DEG), sin(r / RND_RAD_TO_DEG)); + } + vx = x2 - x1; + vy = y2 - y1; + nx = -vy; + ny = vx; + len = rnd_distance(x1, y1, x2, y2); + if (len == 0) + len = 1; + nx /= len; + ny /= len; + pb = pa_rect( + rnd_round(x1 - nx*th/2.0), rnd_round(y1 - ny*th/2.0), + rnd_round(x2 - nx*th/2.0), rnd_round(y2 - ny*th/2.0), + rnd_round(x2 + nx*th/2.0), rnd_round(y2 + ny*th/2.0), + rnd_round(x1 + nx*th/2.0), rnd_round(y1 + ny*th/2.0)); + macro_line_render_merge(dst, pb, pol); + return 0; + case GEMO_LINE_WH: + pol = param_eval_int(l, 1, param); + w = param_eval_crd(ctx, l, 2, param); + h = param_eval_crd(ctx, l, 3, param); + x = param_eval_crd(ctx, l, 4, param); + y = param_eval_crd(ctx, l, 5, param); + r = param_eval_dbl(l, 6, param) + rot; + x1 = x - w/2; x2 = x + w/2; + y1 = y2 = y; + th = h; + goto line_xy; + case GEMO_SET: + n = l->idx; + r = param_eval_dbl(l, 1, param); + vtd0_set(param, n-1, r); + return 0; + } + + return -1; +} + +/* Render a macro aperture using a macro def into a polygon */ +static camv_any_obj_t *aper_macro_render(ge_aper_t *aper, gedraw_ctx_t *ctx, double rot) +{ + rnd_polyarea_t *pa; + const ge_aper_macro_t *am = aper->data.macro.am; + const ge_macro_line_t *l; + vtd0_t param; + + /* need a copy of the parameters because they may change ($n=... in macro) */ + vtd0_init(¶m); + vtd0_copy(¶m, 0, &aper->data.macro.param, 0, aper->data.macro.param.used); + + pa = NULL; + for(l = am->line1; l != NULL; l = l->next) + macro_line_render(ctx, &pa, l, ¶m, rot); + + if (pa == NULL) { + rnd_message(RND_MSG_WARNING, "aperture macro results in empty render\n"); + return NULL; + } + return polyarea2camv(pa); +} + + +static camv_any_obj_t *gedraw_render_aper_nohole(camv_design_t *camv, gedraw_ctx_t *ctx, ge_aper_t *aper, rnd_coord_t ox, rnd_coord_t oy, double rot) +{ + camv_any_obj_t *o; + double rx, ry; + int n; + + switch(aper->shape) { + case GEA_CIRC: + o = (camv_any_obj_t *)camv_line_new(); + o->line.x1 = o->line.x2 = ox; + o->line.y1 = o->line.y2 = oy; + o->line.thick = aper->data.circ.dia; + return o; + + case GEA_RECT: + o = (camv_any_obj_t *)camv_poly_new(); + camv_poly_allocpts(&o->poly, 4); + + rx = ((double)aper->data.rect.xs / 2.0); + ry = ((double)aper->data.rect.ys / 2.0); + + o->poly.x[3] = rnd_round((double)ox - rx); + o->poly.y[3] = rnd_round((double)oy - ry); + o->poly.x[2] = rnd_round((double)ox + rx); + o->poly.y[2] = rnd_round((double)oy - ry); + o->poly.x[1] = rnd_round((double)ox + rx); + o->poly.y[1] = rnd_round((double)oy + ry); + o->poly.x[0] = rnd_round((double)ox - rx); + o->poly.y[0] = rnd_round((double)oy + ry); + if (rot != 0) { + rot = rot / RND_RAD_TO_DEG; + for(n = 0; n < 4; n++) + rnd_rotate(&o->poly.x[n], &o->poly.y[n], ox, oy, cos(rot), sin(rot)); + } + + return o; + + case GEA_OBLONG: + if (aper->cached == NULL) + aper->cached = aper_oblong2poly(aper, rot); + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + case GEA_POLY: + if (aper->cached == NULL) + aper->cached = aper_poly2poly_nohole(aper, rot); + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + case GEA_MACRO: + if (aper->cached == NULL) + aper->cached = aper_macro_render(aper, ctx, rot); + if (aper->cached == NULL) /* aperture creation may fail on empty aper */ + return NULL; + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + } + return NULL; +} + +static camv_any_obj_t *gedraw_render_aper_hole(camv_design_t *camv, gedraw_ctx_t *ctx, ge_aper_t *aper, rnd_coord_t ox, rnd_coord_t oy, double rot) +{ + camv_any_obj_t *o; + rnd_polyarea_t *pdiff, *ps, *ph; + double rx, ry; + +TODO("Generate and cache these and dup with offset instead of reconstructing all the time"); + switch(aper->shape) { + case GEA_CIRC: + if (aper->cached == NULL) { + ps = rnd_poly_from_circle(0, 0, aper->data.circ.dia/2); + ph = rnd_poly_from_circle(0, 0, aper->hole/2); + rnd_polyarea_boolean_free(ps, ph, &pdiff, RND_PBO_SUB); + aper->cached = polyarea2camv(pdiff); + } + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + + case GEA_RECT: + if (aper->cached == NULL) { + rx = ((double)aper->data.rect.xs / 2.0); + ry = ((double)aper->data.rect.ys / 2.0); + ps = rnd_poly_from_rect(-rx, +rx, -ry, +ry); + ph = rnd_poly_from_circle(0, 0, aper->hole/2); + rnd_polyarea_boolean_free(ps, ph, &pdiff, RND_PBO_SUB); + aper->cached = polyarea2camv(pdiff); + } + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + case GEA_OBLONG: + if (aper->cached == NULL) + aper->cached = aper_oblong2poly(aper, rot); /* handles the hole */ + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + case GEA_POLY: + if (aper->cached == NULL) + aper->cached = aper_poly2poly_hole(aper, rot); + o = camv_obj_dup(aper->cached); + o->proto.calls->move(o, ox, oy); + return o; + + case GEA_MACRO: + return gedraw_render_aper_nohole(camv, ctx, aper, ox, oy, rot); + } + + return NULL; +} + +/* render an aperture at x;y into a camv drawing primitive (may be a grp). + Rot is in deg in gerb notation; x;y are in gerber notation. */ +static camv_any_obj_t *gedraw_render_aper(camv_design_t *camv, gedraw_ctx_t *ctx, ge_aper_t *aper, rnd_coord_t ox, rnd_coord_t oy, double rot) +{ + if (aper->hole == 0) + return gedraw_render_aper_nohole(camv, ctx, aper, ox, oy, rot); + else + return gedraw_render_aper_hole(camv, ctx, aper, ox, oy, rot); +} + + +/*** gerber state machine ***/ + +static int gedraw_aper_store(gedraw_ctx_t *ctx, long aid, const ge_aper_t *aper) +{ + if (!ctx->aper_inited) { + htip_init(&ctx->aper, longhash, longkeyeq); + ctx->aper_inited = 1; + } + + if (htip_has(&ctx->aper, aid)) { + static int explained = 0; + rnd_message(RND_MSG_WARNING, "gedraw_aper_store: aperture %ld is re-defined\n", aid); + if (!explained) { + rnd_message(RND_MSG_WARNING, "This is not necessarily an error, but is probably bad\npractice and is dangerous: some gerber viewers will break on this\n", aid); + explained = 1; + } + } + + htip_set(&ctx->aper, aid, (ge_aper_t *)aper); /* can remember by pointer because it's coming from the VM code */ + return 0; +} + +static ge_aper_t *gedraw_aper_get(gedraw_ctx_t *ctx, long aid) +{ + if (!ctx->aper_inited) + return NULL; + return htip_get(&ctx->aper, aid); +} + +typedef struct { + rnd_coord_t x, y, i, j; + gedraw_cmd_t op; + long aper; + ge_interp_t interp; + ge_quadr_t quadr; + long sets; /* number of set instructions within the block */ + unsigned relcrd:1; + unsigned relat:1; + unsigned poly:1; + unsigned clearing:1; +} gerbst_t; + + +static void gedraw_poly_close(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly) +{ + rnd_cardinal_t n, i; + camv_any_obj_t *o; + + if (ctx->contour.used == 0) + return; + if (ctx->contour.used < 6) { + rnd_message(RND_MSG_ERROR, "gedraw_poly_close: contour with too few vertices (%d)\n", ctx->contour.used/2); + ctx->contour.used = 0; + return; + } + if (!ctx->poly_closed) + rnd_message(RND_MSG_ERROR, "gedraw_poly_close: contour is not closed\n"); + + o = (camv_any_obj_t *)camv_poly_new(); + camv_poly_allocpts(&o->poly, ctx->contour.used/2); + for(n = 0, i = 0; i < ctx->contour.used; n++) { + o->poly.x[n] = ctx->contour.array[i++]; + o->poly.y[n] = ctx->contour.array[i++]; + } + camv_obj_add_to_layer(ly, o); + ctx->contour.used = 0; + ctx->poly_closed = 0; +} + +static void gedraw_poly_append(gedraw_ctx_t *ctx, rnd_coord_t x, rnd_coord_t y) +{ + if ((ctx->contour.used > 5) && (ctx->contour.array[0] == x) && (ctx->contour.array[1] == y)) { + /* arrived back at the start, close and avoid dupliocate */ + ctx->poly_closed = 1; + return; + } + + if ((ctx->contour.used > 1) && (ctx->contour.array[ctx->contour.used-2] == x) && (ctx->contour.array[ctx->contour.used-1] == y)) { + /* new point is the same as last: skip */ + return; + } + + ctx->poly_closed = 0; + vtc0_append(&ctx->contour, x); + vtc0_append(&ctx->contour, y); +} + +#define SETCRD(dst, src) \ + do { \ + if (curr->relcrd) (dst) += (src); \ + else (dst) = (src); \ + } while(0) + +static void gedraw_do_pol_(camv_design_t *camv, const camv_layer_t *main_layer, camv_layer_t **ly, int clearing) +{ + *ly = camv_layer_new(); + (*ly)->sub = 1; + (*ly)->clearing = clearing; + (*ly)->color = main_layer->color; + camv->loader.ly = camv_sublayer_append_after(camv, *ly, camv->loader.ly); +} + +static void gedraw_do_pol(camv_design_t *camv, const camv_layer_t *main_layer, camv_layer_t **ly, gerbst_t *curr, gerbst_t *last) +{ + if (curr->clearing == last->clearing) + return; /* optimization: do not create a new layer with the same polarity */ + gedraw_do_pol_(camv, main_layer, ly, curr->clearing); +} + +static rnd_polyarea_t *pa_rect_side(gerbst_t *c1, gerbst_t *c2, double dx1, double dy1, double dx2, double dy2) +{ + rnd_vector_t v; + rnd_pline_t *pl; + + v[0] = rnd_round((double)c1->x+dx1); + v[1] = rnd_round((double)c1->y+dy1); + pl = rnd_poly_contour_new(v); + + v[0] = rnd_round((double)c2->x+dx1); + v[1] = rnd_round((double)c2->y+dy1); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = rnd_round((double)c2->x+dx2); + v[1] = rnd_round((double)c2->y+dy2); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + v[0] = rnd_round((double)c1->x+dx2); + v[1] = rnd_round((double)c1->y+dy2); + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + + return rnd_poly_from_contour_autoinv(pl); +} + +static void gedraw_do_draw_line(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly, gerbst_t *curr, gerbst_t *last) +{ + camv_any_obj_t *o; + ge_aper_t *aper; + rnd_polyarea_t *slice, *sum, *pres; + double rx, ry; + + if (curr->poly) { + gedraw_poly_append(ctx, ctx->ox + last->x, ctx->oy + last->y); + gedraw_poly_append(ctx, ctx->ox + curr->x, ctx->oy + curr->y); + return; + } + + aper = gedraw_aper_get(ctx, curr->aper); + + switch(aper->shape) { + case GEA_CIRC: + o = (camv_any_obj_t *)camv_line_new(); + o->line.x1 = ctx->ox + last->x; o->line.y1 = ctx->oy + last->y; + o->line.x2 = ctx->ox + curr->x; o->line.y2 = ctx->oy + curr->y; + o->line.thick = aper->data.circ.dia; + camv_obj_add_to_layer(ly, o); + break; + case GEA_RECT: + rx = ((double)aper->data.rect.xs / 2.0); + ry = ((double)aper->data.rect.ys / 2.0); + + if ((last->x == curr->x) || (last->y == curr->y)) { /* cheap corner case: axis aligned line or zero length line */ + double x1, y1, x2, y2; + + x1 = MIN(last->x, curr->x); + x2 = MAX(last->x, curr->x); + y1 = MIN(last->y, curr->y); + y2 = MAX(last->y, curr->y); + + o = (camv_any_obj_t *)camv_poly_new(); + camv_poly_allocpts(&o->poly, 4); + o->poly.x[0] = rnd_round(ctx->ox + x1 - rx); + o->poly.y[0] = rnd_round(ctx->oy + y1 - ry); + o->poly.x[1] = rnd_round(ctx->ox + x2 + rx); + o->poly.y[1] = rnd_round(ctx->oy + y1 - ry); + o->poly.x[2] = rnd_round(ctx->ox + x2 + rx); + o->poly.y[2] = rnd_round(ctx->oy + y2 + ry); + o->poly.x[3] = rnd_round(ctx->ox + x1 - rx); + o->poly.y[3] = rnd_round(ctx->oy + y2 + ry); + camv_obj_add_to_layer(ly, o); + } + else { + sum = rnd_poly_from_rect(ctx->ox + last->x-rx, ctx->ox + last->x+rx, ctx->oy + last->y-ry, ctx->oy + last->y+ry); + slice = rnd_poly_from_rect(ctx->ox + curr->x-rx, ctx->ox + curr->x+rx, ctx->oy + curr->y-ry, ctx->oy + curr->y+ry); + rnd_polyarea_boolean_free(sum, slice, &pres, RND_PBO_UNITE); sum = pres; + + slice = pa_rect_side(last, curr, ctx->ox-rx, ctx->oy-ry, ctx->ox+rx, ctx->oy-ry); /* top horiz */ + rnd_polyarea_boolean_free(sum, slice, &pres, RND_PBO_UNITE); sum = pres; + + slice = pa_rect_side(last, curr, ctx->ox+rx, ctx->oy-ry, ctx->ox+rx, ctx->oy+ry); /* right vert */ + rnd_polyarea_boolean_free(sum, slice, &pres, RND_PBO_UNITE); sum = pres; + + slice = pa_rect_side(last, curr, ctx->ox-rx, ctx->oy+ry, ctx->ox+rx, ctx->oy+ry); /* bottom horiz */ + rnd_polyarea_boolean_free(sum, slice, &pres, RND_PBO_UNITE); sum = pres; + + slice = pa_rect_side(last, curr, ctx->ox-rx, ctx->oy-ry, ctx->ox-rx, ctx->oy+ry); /* left vert */ + rnd_polyarea_boolean_free(sum, slice, &pres, RND_PBO_UNITE); sum = pres; + + o = polyarea2camv(sum); + camv_obj_add_to_layer(ly, o); + } + break; + default: + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW line: linear interpolation is permitted only using round or rectangle apertures\n"); + } + +} + +static void gedraw_do_draw_arc(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly, gerbst_t *curr, gerbst_t *last, int is_cw) +{ + camv_arc_t *arc; + ge_aper_t *aper; + rnd_coord_t cx, cy, r1, r2; + double ang1, ang2, delta; + + if (!curr->poly) { + aper = gedraw_aper_get(ctx, curr->aper); + if (aper == NULL) { + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: invalid aperture %ld\n", curr->aper); + return; + } + + if (aper->shape != GEA_CIRC) { + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: circular interpolation is permitted only with filled circle aperture\n"); + return; + } + } + else + aper = NULL; /* in poly mode no need to use the aperture */ + + if (curr->quadr == GEQ_SINGLE) { + rnd_coord_t i = curr->i, j = curr->j; + /* it seems I;J sign is ignored and reconstructed from last->curr movement */ + if (i < 0) { + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: single quadrant I should be positive\n"); + i = -i; + } + if (j < 0) { + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: single quadrant J should be positive\n"); + j = -j; + } + if (curr->x < last->x) i = -i; + if (curr->y < last->y) j = -j; + cx = last->x + i; + cy = last->y + j; + } + else { + /* in multi-quadrant mode I and J are just signed */ + cx = last->x + curr->i; + cy = last->y + curr->j; + } + + ang1 = atan2(last->y - cy, last->x - cx) * RND_RAD_TO_DEG; + ang2 = atan2(curr->y - cy, curr->x - cx) * RND_RAD_TO_DEG; + + if (ang1 < 0) ang1 += 360; + if (ang2 < 0) ang2 += 360; + + if (curr->quadr == GEQ_SINGLE) { + if (is_cw) { + delta = ang2 - ang1; + if (delta > 90) + delta -= 360; + if ((delta < 0.0) || (delta > 90.0)) + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: single quadrant arc with angle span out of range (CW)\n"); + } + else { + delta = ang1 - ang2; + if (delta < -90) + delta += 360; + if ((delta < -90.0) || (delta > 0.0)) + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: single quadrant arc with angle span out of range (CCW)\n"); + delta = -delta; + } + } + else { + if (is_cw) { /* CW */ + delta = ang1 - ang2; + if (delta < 0) { + delta = 360 + delta; + } + delta = -delta; + } + else { /* CCW */ + delta = ang2 - ang1; + if (delta < 0) + delta = 360 + delta; + } + } + + r1 = rnd_distance(last->x, last->y, cx, cy); + r2 = rnd_distance(curr->x, curr->y, cx, cy); + if (RND_ABS(r1 - r2) > 2*ctx->acceptable_error) + rnd_message(RND_MSG_ERROR, "gedraw_do: DRAW arc: not circular: radius %.6mm vs. %.6mm\n", (rnd_coord_t)rnd_round(r1), (rnd_coord_t)rnd_round(r2)); + + if (curr->poly) { + double a, a1, a2, dlt, step; + + if (delta == 0) /* zero length arc means no modification to a poly contour */ + return; + + if ((delta < 0) && (ang2 > ang1)) ang2 -= 360; + if ((delta > 0) && (ang1 > ang2)) ang1 -= 360; + + dlt = delta / RND_RAD_TO_DEG; + a1 = ang1 / RND_RAD_TO_DEG; + a2 = ang2 / RND_RAD_TO_DEG; + step = (RND_COORD_TO_MM(r1)*8.0); + if (step < 4) + step = 4; + step = dlt / step; + for(a = a1; (step < 0) ? (a > a2) : (a < a2); a += step) + gedraw_poly_append(ctx, rnd_round(ctx->ox + cx + cos(a) * r1), rnd_round(ctx->oy + cy + sin(a) * r1)); + + gedraw_poly_append(ctx, ctx->ox + curr->x, ctx->oy + curr->y); /* make sure we arrive at the endpoint requested */ + return; + } + + arc = camv_arc_new(); + arc->cx = ctx->ox + cx; arc->cy = ctx->oy + cy; arc->r = r1; + arc->thick = aper == NULL ? 0 : aper->data.circ.dia; + arc->start = 180 - ang1; + arc->delta = -delta; + camv_obj_add_to_layer(ly, (camv_any_obj_t *)arc); +} + +static void gedraw_do_draw(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly, gerbst_t *curr, gerbst_t *last) +{ + switch(curr->interp) { + case GEI_LIN: gedraw_do_draw_line(camv, ctx, ly, curr, last); break; + case GEI_CW: gedraw_do_draw_arc(camv, ctx, ly, curr, last, 1); break; + case GEI_CCW: gedraw_do_draw_arc(camv, ctx, ly, curr, last, 0); break; + } +} + +static void gedraw_do_move(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly, gerbst_t *curr, gerbst_t *last) +{ + /* auto-close poly contour on _real_ move; a move that stats in place is not + really a move and shouldn't break the contour - this is how the reference + viewer v2018.11b works */ + if ((curr->poly) && ((curr->x != last->x) || (curr->y != last->y))) { + if (ctx->contour.used > 2) + gedraw_poly_close(camv, ctx, ly); + else + ctx->contour.used = 0; /* do not throw warnings in gedraw_poly_close() but make sure the poly is clean */ + return; + } + /* normal draw: do nothing, coords are getting updated on the curr-to-last copy */ +} + +static void gedraw_do_flash(camv_design_t *camv, gedraw_ctx_t *ctx, camv_layer_t *ly, gerbst_t *curr, gerbst_t *last) +{ + camv_any_obj_t *o; + ge_aper_t *aper = gedraw_aper_get(ctx, curr->aper); + + if (aper == NULL) + return; + o = gedraw_render_aper(camv, ctx, aper, curr->x + ctx->ox, curr->y + ctx->oy, 0); + if (o != NULL) + camv_obj_add_to_layer(ly, o); + else + rnd_message(RND_MSG_ERROR, "gedraw_do: failed to FLASH aperture %ld\n", curr->aper); +} + +static void gedraw_do(camv_design_t *camv, gedraw_ctx_t *ctx, const camv_layer_t *main_layer, camv_layer_t **ly, gerbst_t *curr, gerbst_t *last) +{ + switch(curr->op) { + case GEC_SET_POLCLR: gedraw_do_pol(camv, main_layer, ly, curr, last); break; + case GEC_DRAW: gedraw_do_draw(camv, ctx, *ly, curr, last); break; + case GEC_MOVE: gedraw_do_move(camv, ctx, *ly, curr, last); break; + case GEC_FLASH: gedraw_do_flash(camv, ctx, *ly, curr, last); break; + + case GEC_invalid: + if (!curr->sets) + rnd_message(RND_MSG_WARNING, "gedraw_do: invalid opcode %d (uninitialized #1; probably an empty command sequence terminated by a '*')\n", curr->op); + /* else the command sequence did set some states, so it is okay */ + break; + default: + rnd_message(RND_MSG_ERROR, "gedraw_do: invalid opcode %d (unrecognized #1)\n", curr->op); + } + memcpy(last, curr, sizeof(gerbst_t)); + curr->sets = 0; +} + +static int gedraw_camv_(camv_design_t *camv, gedraw_ctx_t *ctx, const camv_layer_t *main_layer, camv_layer_t **layer, size_t *from, int in_sr, gerbst_t *curr, gerbst_t *last) +{ + size_t n; + camv_layer_t *ly = *layer; + + for(n = *from; n < ctx->code.used; n++) { + gedraw_inst_t *i = &ctx->code.array[n]; /* need to retrieve it each iteration because n may jump after SR */ + switch(i->cmd) { + case GEC_MACRO_DEF: break; /* shouldn't happen */ + + case GEC_SET_X: SETCRD(curr->x, i->data.coord); curr->sets++; break; + case GEC_SET_Y: SETCRD(curr->y, i->data.coord); curr->sets++; break; + case GEC_SET_I: SETCRD(curr->i, i->data.coord); curr->sets++; break; + case GEC_SET_J: SETCRD(curr->j, i->data.coord); curr->sets++; break; + case GEC_SET_RELAT: curr->relat = i->data.on; curr->sets++; break; + case GEC_SET_RELCRD: curr->relcrd = i->data.on; curr->sets++; break; + case GEC_SET_INTERP: curr->interp = i->data.interp; curr->sets++; break; + case GEC_SET_QUADR: curr->quadr = i->data.quadr; curr->sets++; break; + + case GEC_SET_POLY: + if ((curr->poly) && (!i->data.on)) + gedraw_poly_close(camv, ctx, ly); + curr->poly = i->data.on; + curr->sets++; + break; + + case GEC_APER_DEF: + if (gedraw_aper_store(ctx, i->data.aper.id, &i->data.aper) != 0) + return -1; + break; + + case GEC_APER_SEL: + curr->aper = i->data.id; + if (gedraw_aper_get(ctx, curr->aper) == NULL) { + rnd_message(RND_MSG_ERROR, "gedraw_camv: selected invalid (undefined) aperture %ld\n", curr->aper); + return -1; + } + break; + + case GEC_SET_POLCLR: curr->op = i->cmd; curr->clearing = i->data.on; break; + + case GEC_DRAW: + case GEC_MOVE: + case GEC_FLASH: curr->op = i->cmd; break; + + case GEC_DO: gedraw_do(camv, ctx, main_layer, &ly, curr, last); break; + + case GEC_invalid: + rnd_message(RND_MSG_ERROR, "gedraw_camv: invalid opcode %d (uninitialized #2) \n", i->cmd); + break; + + case GEC_STEPREP: + if (!in_sr) { + int nx, ny, vx, vy, was_clearing; + size_t srn; + + was_clearing = ly->clearing; + vx = i->data.steprep.x; + vy = i->data.steprep.y; + if ((vx < 1) && (vy < 1)) { + n++; + goto quit_sr; /* a new SR terminates an already open one */ + } + + if (vx < 1) { + rnd_message(RND_MSG_ERROR, "gedraw_camv: invalid SR x\n"); + return -1; + } + if (vy < 1) { + rnd_message(RND_MSG_ERROR, "gedraw_camv: invalid SR y\n"); + return -1; + } + for(nx = 0; nx < vx; nx++) { + for(ny = 0; ny < vy; ny++) { + gedraw_ctx_t srctx; + gerbst_t srcurr, srlast; + + memcpy(&srctx, ctx, sizeof(gedraw_ctx_t)); + memcpy(&srcurr, curr, sizeof(gerbst_t)); + memcpy(&srlast, last, sizeof(gerbst_t)); + srctx.ox = ctx->ox + nx * i->data.steprep.i; + srctx.oy = ctx->oy + ny * i->data.steprep.j; + srn = n+1; + if (gedraw_camv_(camv, &srctx, main_layer, &ly, &srn, 1, &srcurr, &srlast) != 0) + return -1; + if (was_clearing != ly->clearing) { + /* if last layer doesn't match initial polarity, the only way to restore the original polarity is to create a new sublayer */ + gedraw_do_pol_(camv, main_layer, &ly, was_clearing); + } + } + } + n = srn-1; /* continue with the next instruction after the block */ + } + else { + if ((i->data.steprep.x <= 1) && (i->data.steprep.y <= 1)) + n++; /* closing SR, won't start a loop, skip it */ + goto quit_sr; /* a new SR terminates an already open one */ + } + } + } + + quit_sr:; + *layer = ly; + *from = n; + return 0; +} + +static int gedraw_camv(camv_design_t *camv, gedraw_ctx_t *ctx, const char *name) +{ + size_t from = 0; + camv_layer_t *ly = camv_layer_new(); + gerbst_t curr, last; + + ly->name = rnd_strdup(name); + camv_layer_invent_color(camv, ly); /* gerber files do not have layer color */ + camv->loader.ly = camv_layer_append_to_design(camv, ly); + + memset(&curr, 0, sizeof(curr)); + curr.interp = GEI_LIN; + curr.quadr = GEQ_INVALID; + memcpy(&last, &curr, sizeof(last)); + + return gedraw_camv_(camv, ctx, ly, &ly, &from, 0, &curr, &last); +} + +static int ge_getchar(geparse_ctx_t *ctx) +{ + return fgetc((FILE *)ctx->user_data); +} + +int camv_gerb_load(camv_design_t *camv, const char *fn, FILE *f) +{ + geparse_ctx_t ctx; + ge_parse_res_t res; + int retv; + + memset(&ctx, 0, sizeof(ctx)); + ctx.get_char = ge_getchar; + ctx.user_data = f; + while((res = geparse(&ctx)) == GEP_NEXT) ; + if (res == GEP_ERROR) { + rnd_message(RND_MSG_ERROR, "parse error at %ld:%ld: %s\n", ctx.line, ctx.col, ctx.errmsg); + return -1; + } + + if (ctx.unit == GEU_INCH) + ctx.draw.acceptable_error = RND_INCH_TO_COORD((double)pow(0.1, ctx.cfmt_fra)); + else + ctx.draw.acceptable_error = RND_MM_TO_COORD((double)pow(0.1, ctx.cfmt_fra)); + + ctx.draw.aper_unit = ctx.unit; + retv = gedraw_camv(camv, &ctx.draw, fn); + + if (ctx.draw.aper_inited) { + htip_entry_t *e; + for(e = htip_first(&ctx.draw.aper); e != NULL; e = htip_next(&ctx.draw.aper, e)) { + ge_aper_t *aper = e->value; + if (aper->cached != NULL) + camv_obj_free(aper->cached); + } + htip_uninit(&ctx.draw.aper); + } + + geparse_free(&ctx); + return retv; +} + +static int camv_gerb_test_load(camv_design_t *camv, const char *fn, FILE *f) +{ + char *line, line_[1024]; + int bad = 0; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + while(isspace(*line)) line++; + if (strncmp(line, "M02*", 4) == 0) + return 1; + if (strncmp(line, "%MOIN", 5) == 0) + return 1; + if (strncmp(line, "%MOMM", 5) == 0) + return 1; + if ((strncmp(line, "%ADD", 4) == 0) && (isdigit(line[4]))) + return 1; + bad++; + if (bad > 64) + return 0; + } + return 0; +} + +static camv_io_t io_gerb = { + "gerber", 90, + camv_gerb_test_load, + camv_gerb_load, + NULL, +}; + +int pplg_check_ver_import_gerb(int ver_needed) { return 0; } + +void pplg_uninit_import_gerb(void) +{ + camv_io_unreg(&io_gerb); +} + +int pplg_init_import_gerb(void) +{ + camv_io_reg(&io_gerb); + return 0; +} Index: tags/1.1.4/src_plugins/import_gerb/gex.tab.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gex.tab.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gex.tab.c (revision 818) @@ -0,0 +1,589 @@ +/* original parser id follows */ +/* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */ +/* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */ + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140715 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) +#define YYENOMEM (-2) +#define YYEOF 0 + +#ifndef yyparse +#define yyparse gexparse +#endif /* yyparse */ + +#ifndef yylex +#define yylex gexlex +#endif /* yylex */ + +#ifndef yyerror +#define yyerror gexerror +#endif /* yyerror */ + +#ifndef yychar +#define yychar gexchar +#endif /* yychar */ + +#ifndef yyval +#define yyval gexval +#endif /* yyval */ + +#ifndef yylval +#define yylval gexlval +#endif /* yylval */ + +#ifndef yydebug +#define yydebug gexdebug +#endif /* yydebug */ + +#ifndef yynerrs +#define yynerrs gexnerrs +#endif /* yynerrs */ + +#ifndef yyerrflag +#define yyerrflag gexerrflag +#endif /* yyerrflag */ + +#ifndef yylhs +#define yylhs gexlhs +#endif /* yylhs */ + +#ifndef yylen +#define yylen gexlen +#endif /* yylen */ + +#ifndef yydefred +#define yydefred gexdefred +#endif /* yydefred */ + +#ifndef yydgoto +#define yydgoto gexdgoto +#endif /* yydgoto */ + +#ifndef yysindex +#define yysindex gexsindex +#endif /* yysindex */ + +#ifndef yyrindex +#define yyrindex gexrindex +#endif /* yyrindex */ + +#ifndef yygindex +#define yygindex gexgindex +#endif /* yygindex */ + +#ifndef yytable +#define yytable gextable +#endif /* yytable */ + +#ifndef yycheck +#define yycheck gexcheck +#endif /* yycheck */ + +#ifndef yyname +#define yyname gexname +#endif /* yyname */ + +#ifndef yyrule +#define yyrule gexrule +#endif /* yyrule */ +#define YYPREFIX "gex" + +#define YYPURE 1 + +#line 2 "gex.y" +#include "gexpr.h" +#include +#line 9 "gex.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + double num; + int idx; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +#line 116 "gex.tab.c" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(ge_expr_prglist_t * ctx) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# ifdef YYLEX_PARAM_TYPE +# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLEX_PARAM_TYPE YYLEX_PARAM) +# else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, void * YYLEX_PARAM) +# endif +# define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, ge_expr_prglist_t * ctx) +# define YYLEX yylex(&yylval, ctx) +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(ge_expr_prglist_t * ctx, const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(ctx, msg) +#endif + +extern int YYPARSE_DECL(); + +#define T_NUM 257 +#define T_PARAM 258 +#define UMINUS 259 +#define YYERRCODE 256 +typedef short YYINT; +static const YYINT gexlhs[] = { -1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, +}; +static const YYINT gexlen[] = { 2, + 3, 0, 3, 3, 3, 3, 3, 1, 1, +}; +static const YYINT gexdefred[] = { 0, + 8, 9, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 1, 0, 0, 6, 7, +}; +static const YYINT gexdgoto[] = { 5, + 6, +}; +static const YYINT gexsindex[] = { -40, + 0, 0, 0, -40, -36, -40, -39, -40, -40, -40, + -40, 0, 0, -46, -46, 0, 0, +}; +static const YYINT gexrindex[] = { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 10, 0, 0, +}; +static const YYINT gexgindex[] = { 8, + 0, +}; +#define YYTABLESIZE 218 +static const YYINT gextable[] = { 4, + 11, 13, 4, 8, 3, 9, 8, 11, 9, 5, + 11, 7, 0, 12, 0, 14, 15, 16, 17, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, + 5, 0, 5, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, +}; +static const YYINT gexcheck[] = { 40, + 47, 41, 0, 43, 45, 45, 43, 47, 45, 0, + 47, 4, -1, 6, -1, 8, 9, 10, 11, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 41, -1, 43, -1, 45, -1, -1, + 41, -1, 43, -1, 45, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 120, -1, -1, -1, -1, -1, -1, + 120, -1, -1, 120, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 257, 258, +}; +#define YYFINAL 5 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 259 +#define YYUNDFTOKEN 263 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) +#if YYDEBUG +static const char *const gexname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'('","')'",0,"'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'x'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_NUM", +"T_PARAM","UMINUS",0,0,0,"illegal-symbol", +}; +static const char *const gexrule[] = { +"$accept : expr", +"expr : '(' expr ')'", +"$$1 :", +"expr : '-' $$1 expr", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr 'x' expr", +"expr : expr '/' expr", +"expr : T_NUM", +"expr : T_PARAM", + +}; +#endif + +int yydebug; +int yynerrs; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + YYINT *s_base; + YYINT *s_mark; + YYINT *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; + +#if YYDEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + YYINT *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return YYENOMEM; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return YYENOMEM; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return YYENOMEM; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yyerrflag; + int yychar; + YYSTYPE yyval; + YYSTYPE yylval; + + /* variables for the parser stack */ + YYSTACKDATA yystack; + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = YYEOF; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + YYERROR_CALL("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == YYEOF) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 2: +#line 25 "gex.y" + { gex_append(ctx, PUSH_NUM, 0); } +break; +case 3: +#line 26 "gex.y" + { gex_append(ctx, SUB, 0); } +break; +case 4: +#line 27 "gex.y" + { gex_append(ctx, ADD, 0); } +break; +case 5: +#line 28 "gex.y" + { gex_append(ctx, SUB, 0); } +break; +case 6: +#line 29 "gex.y" + { gex_append(ctx, MUL, 0); } +break; +case 7: +#line 30 "gex.y" + { gex_append(ctx, DIV, 0); } +break; +case 8: +#line 31 "gex.y" + { gex_append(ctx, PUSH_NUM, yystack.l_mark[0].num); } +break; +case 9: +#line 32 "gex.y" + { gex_append_idx(ctx, PUSH_PARAM, yystack.l_mark[0].idx); } +break; +#line 531 "gex.tab.c" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = YYEOF; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == YYEOF) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) + { + goto yyoverflow; + } + *++yystack.s_mark = (YYINT) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + YYERROR_CALL("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} Index: tags/1.1.4/src_plugins/import_gerb/gex.tab.h =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gex.tab.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gex.tab.h (revision 818) @@ -0,0 +1,15 @@ +#define T_NUM 257 +#define T_PARAM 258 +#define UMINUS 259 +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + double num; + int idx; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +extern YYSTYPE gexlval; Index: tags/1.1.4/src_plugins/import_gerb/gex.y =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gex.y (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gex.y (revision 818) @@ -0,0 +1,35 @@ +%{ +#include "gexpr.h" +#include +%} + +%lex-param { ge_expr_prglist_t *ctx } +%parse-param { ge_expr_prglist_t *ctx } + +%union { + double num; + int idx; +} + +%token T_NUM +%token T_PARAM + +%left '+' '-' +%left 'x' '/' +%left UMINUS + +%% + +expr: + '(' expr ')' + | '-' { gex_append(ctx, PUSH_NUM, 0); } + expr %prec UMINUS { gex_append(ctx, SUB, 0); } + | expr '+' expr { gex_append(ctx, ADD, 0); } + | expr '-' expr { gex_append(ctx, SUB, 0); } + | expr 'x' expr { gex_append(ctx, MUL, 0); } + | expr '/' expr { gex_append(ctx, DIV, 0); } + | T_NUM { gex_append(ctx, PUSH_NUM, $1); } + | T_PARAM { gex_append_idx(ctx, PUSH_PARAM, $1); } + ; + +%% Index: tags/1.1.4/src_plugins/import_gerb/gexpr.c =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gexpr.c (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gexpr.c (revision 818) @@ -0,0 +1,153 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer - low level gerber parser + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include "gexpr.h" + +#define STACK_MAX 128 + +#define PUSH(num, is_prm) \ +do { \ + if (sp == sizeof(stack)) \ + return GEEE_STACK_OVERFLOW; \ + stack[sp] = (num); \ + is_param[sp] = is_prm; \ + sp++; \ +} while(0) + +#define POP_(res) \ +do { \ + if (sp == 0) \ + return GEEE_STACK_UNDERFLOW; \ + sp--; \ + res = stack[sp]; \ +} while(0) + +#define POP(res) \ +do { \ + if (sp == 0) \ + return GEEE_STACK_UNDERFLOW; \ + sp--; \ + res = stack[sp]; \ + if (is_param[sp]) { \ + double *__d__; \ + __d__ = vtd0_get(params, res-1, 0); \ + if (__d__ == NULL) \ + res = 0; \ + else \ + res = *__d__; \ + } \ +} while(0) + +#define POP_REQ(res, req_prm) \ +do { \ + POP_(res); \ + if (is_param[sp] != req_prm) \ + return GEEE_INTERNAL; \ +} while(0) + +ge_expr_err_t gex_eval(ge_expr_prg_t *prg, vtd0_t *params, double *res) +{ + char is_param[STACK_MAX]; + double stack[STACK_MAX]; + double o1, o2; + int sp = 0; /* next stack item to use, length of the stack */ + double *d; + + for(;prg != NULL; prg = prg->next) { + switch(prg->inst) { + case PUSH_NUM: + PUSH(prg->payload, 0); + break; + case PUSH_PARAM: + PUSH(prg->payload, 1); + break; + case SET: + d = vtd0_get(params, prg->payload-1, 1); + POP_REQ(*d, 0); + break; + case ADD: + POP(o1); POP(o2); + PUSH(o2+o1, 0); + break; + case SUB: + POP(o1); POP(o2); + PUSH(o2-o1, 0); + break; + case MUL: + POP(o1); POP(o2); + PUSH(o2*o1, 0); + break; + case DIV: + POP(o1); POP(o2); + if (o1 == 0) + return GEEE_DIV0; + PUSH(o2/o1, 0); + break; + } + } + POP(o1); + *res = o1; + return GEEE_SUCCESS; +} + +static ge_expr_prg_t *gex_append_(ge_expr_prglist_t *ctx) +{ + ge_expr_prg_t *ex = malloc(sizeof(ge_expr_prg_t)); + if (ctx->last != NULL) { + ctx->last->next = ex; + ctx->last = ex; + } + else + ctx->first = ctx->last = ex; + + ex->next = NULL; + return ex; +} + +void gex_append(ge_expr_prglist_t *ctx, gexi_t inst, double payload) +{ + ge_expr_prg_t *ex = gex_append_(ctx); + ex->inst = inst; + ex->payload = payload; +} + +void gex_append_idx(ge_expr_prglist_t *ctx, gexi_t inst, int payload) +{ + ge_expr_prg_t *ex = gex_append_(ctx); + ex->inst = inst; + ex->payload = payload; +} + +void gex_free_prg(ge_expr_prg_t *prg) +{ + ge_expr_prg_t *next; + for(; prg != NULL; prg = next) { + next = prg->next; + free(prg); + } +} Index: tags/1.1.4/src_plugins/import_gerb/gexpr.h =================================================================== --- tags/1.1.4/src_plugins/import_gerb/gexpr.h (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/gexpr.h (revision 818) @@ -0,0 +1,53 @@ +#ifndef CAMV_GEX_H +#define CAMV_GEX_H + +#include + +#include "gex.tab.h" + +typedef enum { + PUSH_NUM, /* payload is the number to push */ + PUSH_PARAM, /* push a $N parameter supplied by the caller; payload is the parameter idx */ + SET, /* payload is destination param number, [TOP] is the value */ + + /* these remove [TOP] and [TOP-1], and push the result */ + ADD, + SUB, + MUL, + DIV +} gexi_t; + +typedef struct ge_expr_prg_s ge_expr_prg_t; +struct ge_expr_prg_s { + gexi_t inst; + double payload; + ge_expr_prg_t *next; +}; + +typedef enum { + GEEE_SUCCESS = 0, + GEEE_STACK_OVERFLOW, + GEEE_STACK_UNDERFLOW, + GEEE_DIV0, + GEEE_INTERNAL +} ge_expr_err_t; + + +typedef struct ge_expr_prglist_s { + ge_expr_prg_t *first; + ge_expr_prg_t *last; + void *parent; +} ge_expr_prglist_t; + +extern int gexlex(YYSTYPE *dummy, ge_expr_prglist_t *ctx); +extern int gexerror(ge_expr_prglist_t *ctx, const char *msg); + +void gex_append(ge_expr_prglist_t *ctx, gexi_t inst, double payload); +void gex_append_idx(ge_expr_prglist_t *ctx, gexi_t inst, int payload); + +ge_expr_err_t gex_eval(ge_expr_prg_t *prg, vtd0_t *params, double *res); + +void gex_free_prg(ge_expr_prg_t *prg); + + +#endif Index: tags/1.1.4/src_plugins/import_gerb/import_gerb.pup =================================================================== --- tags/1.1.4/src_plugins/import_gerb/import_gerb.pup (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/import_gerb.pup (revision 818) @@ -0,0 +1,9 @@ +$class import +$short gerber files +$long Load gerber files +$package import +$state works +$fmt-native no +$fmt-feature-r gerber layer image +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/cases.lht =================================================================== --- tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/cases.lht (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/cases.lht (revision 818) @@ -0,0 +1,729 @@ +ha:pcb-rnd-board-v6 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + text_scale = 0 + text_thick = 0.0 + thickness = 1.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + text_scale = 0 + text_thick = 0.0 + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + text_scale = 0 + text_thick = 0.0 + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 127.0mm + y = 127.0mm + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.185 { + x1=430.0mil; y1=325.0mil; x2=810.0mil; y2=235.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.188 { + x1=590.0mil; y1=530.0mil; x2=965.0mil; y2=440.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.191 { + x1=720.0mil; y1=445.0mil; x2=340.0mil; y2=535.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.799 { + x1=875.0mil; y1=3.925in; x2=26.035mm; y2=3.925in; thickness=20.0mil; clearance=40.0mil; + } + ha:line.802 { + x1=26.035mm; y1=3.925in; x2=975.0mil; y2=99.06mm; thickness=20.0mil; clearance=40.0mil; + } + ha:line.805 { + x1=975.0mil; y1=99.06mm; x2=975.0mil; y2=3.95in; thickness=20.0mil; clearance=40.0mil; + } + ha:line.808 { + x1=975.0mil; y1=3.95in; x2=26.035mm; y2=3.925in; thickness=20.0mil; clearance=40.0mil; + } + ha:polygon.12 { clearance=40.0mil; + li:geometry { + ta:contour { + { 475.0mil; 26.035mm } + { 375.0mil; 850.0mil } + { 250.0mil; 26.035mm } + { 350.0mil; 1000.0mil } + { 275.0mil; 1.175in } + { 350.0mil; 27.305mm } + { 350.0mil; 31.75mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.21 { clearance=40.0mil; + li:geometry { + ta:contour { + { 850.0mil; 825.0mil } + { 750.0mil; 650.0mil } + { 625.0mil; 825.0mil } + { 725.0mil; 800.0mil } + { 650.0mil; 975.0mil } + { 725.0mil; 875.0mil } + { 725.0mil; 26.67mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.117 { clearance=40.0mil; + li:geometry { + ta:contour { + { 1.1in; 1.175in } + { 1000.0mil; 1000.0mil } + { 875.0mil; 1.175in } + { 975.0mil; 29.21mm } + { 900.0mil; 33.655mm } + { 995.0mil; 33.147mm } + { 975.0mil; 1.4in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.162 { clearance=40.0mil; + li:geometry { + ta:contour { + { 37.465mm; 975.0mil } + { 1.375in; 800.0mil } + { 31.75mm; 975.0mil } + { 1.35in; 950.0mil } + { 1.275in; 1.125in } + { 1.37in; 28.067mm } + { 1.35in; 30.48mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.293 { clearance=40.0mil; + li:geometry { + ta:contour { + { 450.0mil; 48.895mm } + { 525.0mil; 1.725in } + { 700.0mil; 46.355mm } + { 750.0mil; 54.61mm } + { 575.0mil; 53.975mm } + { 650.0mil; 51.435mm } + { 525.0mil; 2.0in } + { 575.0mil; 1.9in } + { 475.0mil; 1.975in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.304 { clearance=40.0mil; + li:geometry { + ta:contour { + { 1.1in; 48.895mm } + { 1.175in; 1.725in } + { 1.35in; 46.355mm } + { 1.4in; 54.61mm } + { 1.225in; 53.975mm } + { 1.3in; 51.435mm } + { 1.175in; 2.0in } + { 1.225in; 1.9in } + { 1.125in; 1.975in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.811 { clearance=40.0mil; + li:geometry { + ta:contour { + { 425.0mil; 3.325in } + { 500.0mil; 79.375mm } + { 675.0mil; 81.915mm } + { 650.0mil; 3.375in } + { 700.0mil; 86.995mm } + { 650.0mil; 86.36mm } + { 675.0mil; 88.9mm } + { 725.0mil; 90.17mm } + { 550.0mil; 89.535mm } + { 625.0mil; 86.995mm } + { 500.0mil; 86.36mm } + { 550.0mil; 3.3in } + { 450.0mil; 3.375in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.825 { clearance=40.0mil; + li:geometry { + ta:contour { + { 450.0mil; 3.925in } + { 525.0mil; 3.725in } + { 700.0mil; 97.155mm } + { 675.0mil; 100.965mm } + { 725.0mil; 4.025in } + { 675.0mil; 4.0in } + { 700.0mil; 104.14mm } + { 750.0mil; 4.15in } + { 575.0mil; 104.775mm } + { 650.0mil; 4.025in } + { 525.0mil; 4.0in } + { 575.0mil; 99.06mm } + { 475.0mil; 100.965mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.839 { clearance=40.0mil; + li:geometry { + ta:contour { + { 1.125in; 3.925in } + { 30.48mm; 3.725in } + { 1.375in; 97.155mm } + { 1.35in; 100.965mm } + { 1.4in; 4.025in } + { 1.356in; 4.025in } + { 1.375in; 104.14mm } + { 36.195mm; 4.15in } + { 31.75mm; 104.775mm } + { 33.655mm; 4.025in } + { 30.48mm; 4.0in } + { 30.7848mm; 100.965mm } + { 29.21mm; 100.965mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.853 { clearance=40.0mil; + li:geometry { + ta:contour { + { 450.0mil; 4.65in } + { 525.0mil; 113.03mm } + { 700.0mil; 115.57mm } + { 675.0mil; 4.7in } + { 725.0mil; 120.65mm } + { 681.0mil; 120.65mm } + { 700.0mil; 122.555mm } + { 750.0mil; 123.825mm } + { 575.0mil; 4.85in } + { 650.0mil; 120.65mm } + { 525.0mil; 120.015mm } + { 537.0mil; 4.7in } + { 475.0mil; 4.7in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.867 { clearance=40.0mil; + li:geometry { + ta:contour { + { 1.1in; 4.65in } + { 1.175in; 113.03mm } + { 1.35in; 115.57mm } + { 33.655mm; 4.7in } + { 1.375in; 120.65mm } + { 33.8074mm; 120.65mm } + { 1.35in; 122.555mm } + { 1.4in; 123.825mm } + { 1.225in; 4.85in } + { 1.3in; 120.65mm } + { 1.175in; 120.015mm } + { 1.187in; 4.7in } + { 1.125in; 4.7in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1124 { clearance=40.0mil; + li:geometry { + ta:contour { + { 8.53243mm; 71.912251mm } + { 8.395713mm; 66.488532mm } + { 13.468546mm; 67.178452mm } + { 14.307036mm; 2.7932637in } + { 15.960309mm; 71.650671mm } + { 14.544911mm; 71.53766mm } + { 16.085173mm; 73.654831mm } + { 17.738447mm; 74.356605mm } + { 13.37924mm; 75.432969mm } + { 14.194024mm; 72.364297mm } + { 11.01234mm; 72.964911mm } + { 11.238363mm; 70.134113mm } + { 9.596942mm; 72.851899mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1138 { clearance=40.0mil; + li:geometry { + ta:contour { + { 23.840235mm; 65.727496mm } + { 23.703519mm; 60.303777mm } + { 28.776352mm; 60.993697mm } + { 29.614841mm; 64.764143mm } + { 31.268115mm; 65.465916mm } + { 29.852716mm; 65.352905mm } + { 31.392979mm; 67.470077mm } + { 33.046253mm; 68.17185mm } + { 28.687045mm; 69.248214mm } + { 29.50183mm; 66.179542mm } + { 26.320146mm; 2.62914in } + { 26.546169mm; 63.949359mm } + { 24.904747mm; 66.667145mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.314 { + string={Horizontal:}; x=300.0mil; y=1.55in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.378 { + string={Horizontal:}; x=275.0mil; y=2.325in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:line.32 { + x1=375.0mil; y1=850.0mil; x2=750.0mil; y2=650.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.35 { + x1=250.0mil; y1=26.035mm; x2=625.0mil; y2=825.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.38 { + x1=275.0mil; y1=1.175in; x2=650.0mil; y2=975.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.41 { + x1=350.0mil; y1=1000.0mil; x2=725.0mil; y2=800.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.44 { + x1=350.0mil; y1=31.75mm; x2=725.0mil; y2=26.67mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.47 { + x1=350.0mil; y1=27.305mm; x2=725.0mil; y2=875.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.50 { + x1=475.0mil; y1=26.035mm; x2=850.0mil; y2=825.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.133 { + x1=1000.0mil; y1=1000.0mil; x2=1.375in; y2=800.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.136 { + x1=875.0mil; y1=1.175in; x2=31.75mm; y2=975.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.139 { + x1=900.0mil; y1=33.655mm; x2=1.275in; y2=1.125in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.142 { + x1=975.0mil; y1=29.21mm; x2=1.35in; y2=950.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.145 { + x1=975.0mil; y1=1.4in; x2=1.35in; y2=30.48mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.151 { + x1=1.1in; y1=1.175in; x2=37.465mm; y2=975.0mil; thickness=1.0mil; clearance=40.0mil; + } + ha:line.170 { + x1=995.0mil; y1=33.147mm; x2=1.37in; y2=28.067mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.336 { + x1=750.0mil; y1=54.61mm; x2=1.4in; y2=54.61mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.339 { + x1=525.0mil; y1=1.725in; x2=1.175in; y2=1.725in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.345 { + x1=475.0mil; y1=1.975in; x2=540.0mil; y2=1.975in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.699 { + x1=0.0; y1=2.25in; x2=127.0mm; y2=2.25in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.881 { + x1=475.0mil; y1=100.965mm; x2=575.0mil; y2=100.965mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.884 { + x1=725.0mil; y1=4.025in; x2=675.0mil; y2=4.025in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.887 { + x1=525.0mil; y1=113.03mm; x2=1.175in; y2=113.03mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.890 { + x1=750.0mil; y1=123.825mm; x2=1.4in; y2=123.825mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1152 { + x1=8.395713mm; y1=66.488532mm; x2=23.703519mm; y2=60.303777mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1155 { + x1=17.738447mm; y1=74.356605mm; x2=33.046253mm; y2=68.17185mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1158 { + x1=9.596942mm; y1=72.851899mm; x2=24.904747mm; y2=66.667145mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1161 { + x1=31.268115mm; y1=65.465916mm; x2=15.960309mm; y2=71.650671mm; thickness=1.0mil; clearance=40.0mil; + } + ha:polygon.176 { clearance=40.0mil; + li:geometry { + ta:contour { + { 430.0mil; 325.0mil } + { 340.0mil; 535.0mil } + { 590.0mil; 530.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.181 { clearance=40.0mil; + li:geometry { + ta:contour { + { 810.0mil; 235.0mil } + { 720.0mil; 445.0mil } + { 970.0mil; 440.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + ha:text.893 { + string={step1: rotate}; x=325.0mil; y=3.05in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.894 { + string={step2: semi-convex}; x=325.0mil; y=92.075mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.895 { + string={step3: dup and connect}; x=325.0mil; y=107.95mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + + li:objects { + } + color = {#8b7355} + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:slot-plated { + lid=13 + group=14 + ha:combining { auto=1; } + + li:objects { + } + color = {#8b7355} + } + + ha:slot-unplated { + lid=14 + group=15 + ha:combining { auto=1; } + + li:objects { + } + color = {#00868b} + } + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 9; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 8; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 10; } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; } + } + ha:4 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:6 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:8 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:9 { + name = global_outline + ha:type { boundary=1; } + li:layers { 6; } + purpose = uroute + } + ha:10 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; } + } + ha:11 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:14 { + name = pmech + ha:type { mech=1; } + li:layers { 13; } + purpose = proute + } + ha:15 { + name = umech + ha:type { mech=1; } + li:layers { 14; } + purpose = uroute + } + } + } +} Index: tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/final.lht =================================================================== --- tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/final.lht (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/poly-brush/doc/final.lht (revision 818) @@ -0,0 +1,524 @@ +ha:pcb-rnd-board-v6 { + + li:styles { + ha:Signal { + diameter = 2.0mm + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + text_scale = 0 + text_thick = 0.0 + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + text_scale = 0 + text_thick = 0.0 + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 31.75mm + y = 67.31mm + } + board_name = + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.1305 { + x1=650.0mil; y1=1.65in; x2=800.0mil; y2=1.65in; thickness=20.0mil; clearance=40.0mil; + } + ha:line.1308 { + x1=800.0mil; y1=1.65in; x2=750.0mil; y2=1.625in; thickness=20.0mil; clearance=40.0mil; + } + ha:line.1311 { + x1=750.0mil; y1=1.625in; x2=750.0mil; y2=42.545mm; thickness=20.0mil; clearance=40.0mil; + } + ha:line.1314 { + x1=750.0mil; y1=42.545mm; x2=800.0mil; y2=1.65in; thickness=20.0mil; clearance=40.0mil; + } + ha:polygon.1318 { clearance=40.0mil; + li:geometry { + ta:contour { + { 200.0mil; 26.67mm } + { 275.0mil; 850.0mil } + { 450.0mil; 950.0mil } + { 425.0mil; 1.1in } + { 475.0mil; 29.21mm } + { 425.0mil; 1.125in } + { 450.0mil; 1.225in } + { 500.0mil; 1.275in } + { 325.0mil; 31.75mm } + { 400.0mil; 29.21mm } + { 275.0mil; 1.125in } + { 325.0mil; 26.035mm } + { 225.0mil; 1.1in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1332 { clearance=40.0mil; + li:geometry { + ta:contour { + { 225.0mil; 1.65in } + { 300.0mil; 36.83mm } + { 475.0mil; 1.55in } + { 450.0mil; 43.18mm } + { 500.0mil; 44.45mm } + { 450.0mil; 1.725in } + { 475.0mil; 46.355mm } + { 525.0mil; 47.625mm } + { 350.0mil; 46.99mm } + { 425.0mil; 44.45mm } + { 300.0mil; 1.725in } + { 350.0mil; 1.625in } + { 250.0mil; 43.18mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1346 { clearance=40.0mil; + li:geometry { + ta:contour { + { 900.0mil; 1.65in } + { 975.0mil; 36.83mm } + { 29.21mm; 1.55in } + { 1.125in; 43.18mm } + { 1.175in; 44.45mm } + { 1.131in; 44.45mm } + { 29.21mm; 46.355mm } + { 30.48mm; 47.625mm } + { 26.035mm; 46.99mm } + { 1.1in; 44.45mm } + { 975.0mil; 1.725in } + { 987.0mil; 43.18mm } + { 925.0mil; 43.18mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1360 { clearance=40.0mil; + li:geometry { + ta:contour { + { 225.0mil; 60.325mm } + { 300.0mil; 2.175in } + { 475.0mil; 57.785mm } + { 450.0mil; 2.425in } + { 500.0mil; 62.865mm } + { 456.0mil; 62.865mm } + { 475.0mil; 2.55in } + { 525.0mil; 2.6in } + { 350.0mil; 65.405mm } + { 425.0mil; 62.865mm } + { 300.0mil; 2.45in } + { 312.0mil; 2.425in } + { 250.0mil; 2.425in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1374 { clearance=40.0mil; + li:geometry { + ta:contour { + { 875.0mil; 60.325mm } + { 950.0mil; 2.175in } + { 1.125in; 57.785mm } + { 1.1in; 2.425in } + { 29.21mm; 62.865mm } + { 1.106in; 62.865mm } + { 1.125in; 2.55in } + { 1.175in; 2.6in } + { 1000.0mil; 65.405mm } + { 27.305mm; 62.865mm } + { 950.0mil; 2.45in } + { 962.0mil; 2.425in } + { 900.0mil; 2.425in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1388 { clearance=40.0mil; + li:geometry { + ta:contour { + { 2.81743mm; 14.127251mm } + { 2.680713mm; 8.703532mm } + { 7.753546mm; 9.393452mm } + { 8.592036mm; 13.163898mm } + { 10.245309mm; 13.865671mm } + { 8.829911mm; 13.75266mm } + { 10.370173mm; 15.869831mm } + { 12.023447mm; 16.571605mm } + { 7.66424mm; 17.647969mm } + { 8.479024mm; 14.579297mm } + { 5.29734mm; 15.179911mm } + { 5.523363mm; 12.349113mm } + { 3.881942mm; 15.066899mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.1402 { clearance=40.0mil; + li:geometry { + ta:contour { + { 18.125235mm; 7.942496mm } + { 17.988519mm; 2.518777mm } + { 23.061352mm; 3.208697mm } + { 23.899841mm; 6.979143mm } + { 25.553115mm; 7.680916mm } + { 24.137716mm; 7.567905mm } + { 25.677979mm; 9.685077mm } + { 27.331253mm; 10.38685mm } + { 22.972045mm; 11.463214mm } + { 23.78683mm; 8.394542mm } + { 20.605146mm; 8.995156mm } + { 20.831169mm; 6.164359mm } + { 19.189747mm; 8.882145mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.1317 { + string={Horizontal:}; x=50.0mil; y=50.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:line.1416 { + x1=250.0mil; y1=43.18mm; x2=350.0mil; y2=43.18mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1419 { + x1=500.0mil; y1=44.45mm; x2=450.0mil; y2=44.45mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1422 { + x1=300.0mil; y1=2.175in; x2=950.0mil; y2=2.175in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1425 { + x1=525.0mil; y1=2.6in; x2=1.175in; y2=2.6in; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1428 { + x1=2.680713mm; y1=8.703532mm; x2=17.988519mm; y2=2.518777mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1431 { + x1=12.023447mm; y1=16.571605mm; x2=27.331253mm; y2=10.38685mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1434 { + x1=3.881942mm; y1=15.066899mm; x2=19.189747mm; y2=8.882145mm; thickness=1.0mil; clearance=40.0mil; + } + ha:line.1437 { + x1=25.553115mm; y1=7.680916mm; x2=10.245309mm; y2=13.865671mm; thickness=1.0mil; clearance=40.0mil; + } + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + ha:text.1440 { + string={step1: rotate}; x=100.0mil; y=750.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.1441 { + string={step2: semi-convex}; x=100.0mil; y=1.35in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.1442 { + string={step3: dup and connect}; x=100.0mil; y=1.975in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + + li:objects { + } + color = {#8b7355} + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:slot-plated { + lid=13 + group=14 + ha:combining { auto=1; } + + li:objects { + } + color = {#8b7355} + } + + ha:slot-unplated { + lid=14 + group=15 + ha:combining { auto=1; } + + li:objects { + } + color = {#00868b} + } + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 9; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 8; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 10; } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; } + } + ha:4 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:6 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:8 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:9 { + name = global_outline + ha:type { boundary=1; } + li:layers { 6; } + purpose = uroute + } + ha:10 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; } + } + ha:11 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:14 { + name = pmech + ha:type { mech=1; } + li:layers { 13; } + purpose = proute + } + ha:15 { + name = umech + ha:type { mech=1; } + li:layers { 14; } + purpose = uroute + } + } + } +} Index: tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404a.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404a.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404a.gbr (revision 818) @@ -0,0 +1,3 @@ +G04 Source: https://github.com/gerbv/gerbv/issues/56 * +%AMX0*$-100000000=352943162147351756800*% +%ADD09X0*% Index: tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404b.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404b.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1404b.gbr (revision 818) @@ -0,0 +1,3 @@ +G04 Source: https://github.com/gerbv/gerbv/issues/56 * +%AMX0*$-100000000,352943162147351756800=*% +%ADD09X0*% Index: tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1405.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1405.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/TALOS-2021-1405.gbr (revision 818) @@ -0,0 +1,5 @@ +G04 Source: https://github.com/gerbv/gerbv/issues/57 * +%AMX0*4,0,1073741977, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 +*% +%ADD09X0* Index: tags/1.1.4/src_plugins/import_gerb/regression/Tcomment.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/Tcomment.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/Tcomment.gbr (revision 818) @@ -0,0 +1,17 @@ +G04 fancy comments with long command T * +%TF.CreationDate,2021-01-02T03:04:05-06:07*% +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + +%TA.AperFunction,SMDPad,CuDef*% +%ADD11C,0.7000*% +%TD*% + +%TO.P,FID1,*% +%TO.N,*% +G54D11*X10000Y00000D03* +G54D11*X10000Y01000D02*Y02000D01* +%TD*% + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am1.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am1.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am1.gbr (revision 818) @@ -0,0 +1,13 @@ +G04 C shaped aperture * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%AMDONUT* +1,1,$1,0.0,0.0* +1,0,$2,0.2,0.0* +% +%ADD11DONUT,0.60X0.40*% +G54D11*X10000Y00000D03* +G54D11*X40000Y11000D02*Y02000D01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am2.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am2.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am2.gbr (revision 818) @@ -0,0 +1,55 @@ +G04 all macro aperture primitives * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + +%AMP1* +1,1,5,0.0,0.0,0* +% + +%AMP20* +20,1,0.5,0,0,3,5,45* +% + + +%AMP21* +21,1,0.8,0.5,1,2,45* +% + +%AMP4* +4,1,3,1,1,6,1,8,0,1,1,45* +% + +%AMP5* +5,1,3,0,0,2,15* +% + +%AMP6* +6,1,1,4,0.1,0.5,3,0.05,7,45* +% + + +%AMP7* +7,1,1,3,2.5,0.1,20* +% + + +%ADD11P1*% +%ADD12P20*% +%ADD13P21*% +%ADD14P4*% +%ADD15P5*% +%ADD16P6*% +%ADD17P7*% + + +G54D11*X10000Y00000D03* +G54D12*X20000Y00000D03* +G54D13*X30000Y00000D03* +G54D14*X40000Y00000D03* +G54D15*X50000Y00000D03* +G54D16*X60000Y00000D03* +G54D17*X70000Y00000D03* + + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am2r.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am2r.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am2r.gbr (revision 818) @@ -0,0 +1,69 @@ +G04 rotated aperture macro primitives with a thin -+ line marking a known point * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + +%AMP1* +1,1,0.5,2,3,33* +20,0,0.1,0,0,2,3,33* +20,1,0.05,0,0,2,3,33* +% + +%AMP20* +20,1,0.5,3,5,1,2,45* +20,0,0.1,0,0,1,2,45* +20,1,0.05,0,0,1,2,45* +% + + +%AMP21* +21,1,0.8,0.5,1,2,45* +20,0,0.1,0,0,1,2,45* +20,1,0.05,0,0,1,2,45* +% + +%AMP4* +4,1,3,1,1,6,1,8,0,1,1,45* +20,0,0.1,0,0,1,1,45* +20,1,0.05,0,0,1,1,45* +% + +%AMP5* +5,1,3,2,3,2,15* +20,0,0.1,0,0,2,3,15* +20,1,0.05,0,0,2,3,15* +% + +%AMP6* +6,2,3,4,0.1,0.5,3,0.05,7,45* +20,0,0.1,0,0,2,3,45* +20,1,0.05,0,0,2,3,45* +% + + +%AMP7* +7,2,3,3,2.5,0.1,20* +20,0,0.1,0,0,2,3,20* +20,1,0.05,0,0,2,3,20* +% + + +%ADD11P1*% +%ADD12P20*% +%ADD13P21*% +%ADD14P4*% +%ADD15P5*% +%ADD16P6*% +%ADD17P7*% + + +G54D11*X10000Y10000D03* +G54D12*X20000Y10000D03* +G54D13*X30000Y10000D03* +G54D14*X40000Y10000D03* +G54D15*X50000Y10000D03* +G54D16*X60000Y10000D03* +G54D17*X70000Y10000D03* + + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am3.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am3.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am3.gbr (revision 818) @@ -0,0 +1,17 @@ +G04 aperture with arithmetics * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%AMFOO* +1,1,3,0.0,0.0,0* +0, comment * +$3=($1-0.05)x1.5* +1,0,0.1,$3,0.0,0* +1,0,0.2,$1-1,0.0,0* +% +%ADD11FOO,0.50*% +%ADD12FOO,1.00*% +G54D11*X10000Y00000D03* +G54D12*X20000Y00000D03* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am4.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am4.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am4.gbr (revision 818) @@ -0,0 +1,16 @@ +G04 corner case: empty macro * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%AMFOO* +0, comment * +$3=($1-0.05)x1.5* +% +%AMBAR* +% +%ADD11FOO,0.50*% +%ADD12BAR*% +G54D11*X10000Y00000D03* +G54D12*X20000Y00000D03* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am5.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am5.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am5.gbr (revision 818) @@ -0,0 +1,24 @@ +G04 zero sized (on centerline) rectangular lines * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + + +%AMP20* +20,1,1,2,2,2,2,45* +% + + +%AMP21* +21,1,1.0,1.0,1,2,45* +% + +%ADD12P20*% +%ADD13P21*% + + +G54D12*X20000Y00000D03* +G54D13*X30000Y00000D03* + + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am6.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am6.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am6.gbr (revision 818) @@ -0,0 +1,14 @@ +G04 macro aperture primitive 6 corner case * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + +%AMP6* +6,0,0,1.75x2,1,0.5,2,0.01,4.5,0* +% + +%ADD11P6*% + +G54D11*X10000Y00000D03* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am_polyexpr.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am_polyexpr.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am_polyexpr.gbr (revision 818) @@ -0,0 +1,18 @@ +G04 polygonial macro aperture with the first X coord coming from a macro parameter * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% + +%AMPOLY* +4,1,3,$1,1,6,1,8,0,$1,1,45* +% + + +%ADD11POLY,1*% +%ADD12POLY,-9*% + +G54D11*X10000Y00000D03* +G54D12*X20000Y00000D03* + + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/am_set.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/am_set.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/am_set.gbr (revision 818) @@ -0,0 +1,20 @@ +G04 test AM set * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%AMFOO* +0, comment * +$2=1* +$3=$1+1* +$4=$1-1* +1,1,0.5,0.0,0.0,0* +1,1,$2,$3,$4,0* +% +%AMBAR* +% +%ADD11FOO,1*% +%ADD12FOO,-1*% +G54D11*X10000Y00000D03* +G54D12*X20000Y00000D03* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/aper.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/aper.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/aper.gbr (revision 818) @@ -0,0 +1,26 @@ +G04 flash and draw line with different regular apertures * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,1.0000*% +%ADD12R,1.0000X0.5000*% +%ADD13O,1.0000X0.5000*% +%ADD14P,1.0000X3*% +%ADD15P,1.0000X3X30*% +%ADD16P,1.0000X3X30X0.5000*% + +G54D11*X10000Y01000D03* +G54D11*X10000Y11000D02*Y03000D01* + +G54D12*X20000Y01000D03* +G54D12*X20000Y11000D02*Y03000D01* + +G54D13*X30000Y01000D03* +G54D13*X30000Y11000D02*Y03000D01* + +G54D14*X40000Y01000D03* +G54D14*X40000Y11000D02*Y03000D01* + +G54D15*X50000Y01000D03* +G54D15*X50000Y11000D02*Y03000D01* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/aper_hole.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/aper_hole.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/aper_hole.gbr (revision 818) @@ -0,0 +1,25 @@ +G04 flash and draw line with different regular apertures * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,1.0000X0.4000*% +%ADD12R,1.0000X0.5000X0.4000*% +%ADD13O,1.0000X0.5000X0.4000*% +%ADD14P,1.0000X3X0X0.4000*% +%ADD15P,1.0000X3X30X0.4000*% + +G54D11*X10000Y01000D03* +G54D11*X10000Y12000D02*Y12300D01* + +G54D12*X20000Y01000D03* +G54D12*X20000Y12000D02*Y12300D01* + +G54D13*X30000Y01000D03* +G54D13*X30000Y12000D02*Y12300D01* + +G54D14*X40000Y01000D03* +G54D14*X40000Y12000D02*Y12300D01* + +G54D15*X50000Y01000D03* +G54D15*X50000Y12000D02*Y12300D01* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_all.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_all.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_all.gbr (revision 818) @@ -0,0 +1,27 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: (unknown), top_copper * +G04 Creator: pcb-rnd 2.1.2 * +G04 CreationDate: 2019-06-06 14:34:13 UTC * +G04 For: * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 30000 17500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0010*% +G54D11* + +G74* +X07500Y7500D02*G02X08964Y11036I5000J0D01*G01* + +G74* +X10000Y10000D02*G03X11000Y09000I1000J0000D01*G01* + +G75* +X17500Y7500D02*G02X18964Y11036I5000J0D01*G01* + +G75* +X22500Y7500D02*G03X23964Y11036I5000J0D01*G01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g74.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g74.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g74.gbr (revision 818) @@ -0,0 +1,23 @@ +G04 circle built of 4 single quandrant 1/4th arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.0500*% +%ADD12C,0.0100*% + +G74* + +G04 9..12* +G54D11*X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* + + +G04 12..3* +G54D12*X10000Y11000D02*G02X11000Y10000I00000J01000D01*G01* + +G04 3..6* +G54D11*X11000Y10000D02*G02X10000Y09000I01000J00000D01*G01* + + +G04 6..9* +G54D12*X10000Y09000D02*G02X09000Y10000I00000J01000D01*G01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g74p.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g74p.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g74p.gbr (revision 818) @@ -0,0 +1,25 @@ +G04 circle built of 4 single quandrant 1/4th arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.0500*% + +G74* + +G54D11* +G36* + +G04 9..12* +X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* + + +G04 12..3* +X10000Y11000D02*G02X11000Y10000I00000J01000D01*G01* + +G04 3..6* +X11000Y10000D02*G02X10000Y09000I01000J00000D01*G01* + +G04 6..9* +X10000Y09000D02*G02X09000Y10000I00000J01000D01*G01* +G37* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g75.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g75.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g75.gbr (revision 818) @@ -0,0 +1,23 @@ +G04 circle built of 4 multi quandrant 1/4th arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.0500*% +%ADD12C,0.0100*% + +G75* + +G04 9..12* +G54D11*X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* + + +G04 12..3* +G54D12*X10000Y11000D02*G02X11000Y10000I00000J-01000D01*G01* + +G04 3..6* +G54D11*X11000Y10000D02*G02X10000Y09000I-01000J00000D01*G01* + + +G04 6..9* +G54D12*X10000Y09000D02*G02X09000Y10000I00000J01000D01*G01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g75b.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g75b.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g75b.gbr (revision 818) @@ -0,0 +1,27 @@ +G04 circle built of 4 multi quandrant 3/4th thin arc + 1/4th thick arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.1000*% +%ADD12C,0.0100*% + +G75* + +G04 9..12* +G54D12*X09000Y10000D02*G03X10000Y11000I01000J00000D01*G01* +G54D11*X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* + + +G04 12..3* +G54D12*X20000Y11000D02*G03X21000Y10000I00000J-01000D01*G01* +G54D11*X20000Y11000D02*G02X21000Y10000I00000J-01000D01*G01* + +G04 3..6* +G54D12*X31000Y10000D02*G03X30000Y09000I-01000J00000D01*G01* +G54D11*X31000Y10000D02*G02X30000Y09000I-01000J00000D01*G01* + + +G04 6..9* +G54D12*X40000Y09000D02*G03X39000Y10000I00000J01000D01*G01* +G54D11*X40000Y09000D02*G02X39000Y10000I00000J01000D01*G01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g75bp.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g75bp.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g75bp.gbr (revision 818) @@ -0,0 +1,37 @@ +G04 circle built of 4 multi quandrant 3/4th thin arc + 1/4th thick arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.1000*% +%ADD12C,0.0100*% + +G75* + +G54D11* + +G04 9..12* +G36* +X09000Y10000D02*G03X10000Y11000I01000J00000D01*G01* +X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* +G37* + + +G04 12..3* +G36* +X20000Y11000D02*G03X21000Y10000I00000J-01000D01*G01* +X20000Y11000D02*G02X21000Y10000I00000J-01000D01*G01* +G37* + +G04 3..6* +G36* +X31000Y10000D02*G03X30000Y09000I-01000J00000D01*G01* +X31000Y10000D02*G02X30000Y09000I-01000J00000D01*G01* +G37* + + +G04 6..9* +G36* +X40000Y09000D02*G03X39000Y10000I00000J01000D01*G01* +X40000Y09000D02*G02X39000Y10000I00000J01000D01*G01* +G37* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/arc_g75p.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/arc_g75p.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/arc_g75p.gbr (revision 818) @@ -0,0 +1,27 @@ +G04 circle built of 4 multi quandrant 1/4th arc * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,0.0500*% +%ADD12C,0.0100*% + +G75* + +G54D11* +G36* + +G04 9..12* +X09000Y10000D02*G02X10000Y11000I01000J00000D01*G01* + + +G04 12..3* +X10000Y11000D02*G02X11000Y10000I00000J-01000D01*G01* + +G04 3..6* +X11000Y10000D02*G02X10000Y09000I-01000J00000D01*G01* + + +G04 6..9* +X10000Y09000D02*G02X09000Y10000I00000J01000D01*G01* +G37* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/crd_lead.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/crd_lead.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/crd_lead.gbr (revision 818) @@ -0,0 +1,10 @@ +G04 coords with leading zeros: smaller flash in between the two larger ones * +%MOMM*% +%FSLAX23Y23*% +%ADD11C,1.0000*% +%ADD12C,0.5000*% + +G54D11*X00000Y00000D03* +G54D11*X10000Y10000D03* +G54D12*X5000Y5000D03* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/crd_tail.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/crd_tail.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/crd_tail.gbr (revision 818) @@ -0,0 +1,10 @@ +G04 coords with leading zeros: smaller flash is far away from the two larger ones * +%MOMM*% +%FSTAX23Y23*% +%ADD11C,1.0000*% +%ADD12C,0.5000*% + +G54D11*X00000Y00000D03* +G54D11*X10000Y10000D03* +G54D12*X5000Y5000D03* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/multiadd.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/multiadd.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/multiadd.gbr (revision 818) @@ -0,0 +1,14 @@ +G04 the same aperture 19 redefined multiple times * +G04 reference gerbver viewer always uses the last definition * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD19C,0.0100*% +G54D19*X0Y50000D02*Y0D01* +%ADD19C,0.0200*% +G54D19*Y50000D02*X20000D01* +%ADD19C,0.0300*% +G54D19*X0Y0D02*X20000D01* +%ADD19C,0.0400*% +G54D19*Y50000D02*Y0D01* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/poly1.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/poly1.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/poly1.gbr (revision 818) @@ -0,0 +1,12 @@ +G04 polygon with thin pen * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0001*% +G54D11*G36* +X32500Y20000D02*Y5000D01* +X2500D01* +X17500Y20000D01* +X32500D01* +G37* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/polyarc.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/polyarc.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/polyarc.gbr (revision 818) @@ -0,0 +1,12 @@ +G04 polygon with an arc and a line in the contour * +%MOMM*% +%FSLAX43Y43*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11* +G36* +G75* +X33020Y33020D02*X1905Y1905D01* +X1905Y1905D02*G75*G02X33020Y33020I31115J0D01*G01* +G37* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep.gbr (revision 818) @@ -0,0 +1,12 @@ +G04 step and repeat with explicit termination * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.7000*% +%SRX3Y2I3.0J6.0*% +G54D11*X10000Y00000D03* +G54D11*X10000Y01000D02*Y02000D01* +%SR*% + +G54D11*X10000Y01000D02*X12000D01* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep2.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep2.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep2.gbr (revision 818) @@ -0,0 +1,9 @@ +G04 step and repeat with implicit termination * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.7000*% +%SRX3Y2I3.0J6.0*% +G54D11*X10000Y00000D03* +G54D11*X10000Y01000D02*Y02000D01* +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep3.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep3.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep3.gbr (revision 818) @@ -0,0 +1,14 @@ +G04 recursive step and repeat seems to be impossible, each new SR closes the old * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.7000*% +%ADD12C,0.1000*% +%SRX2Y2I10.0J10.0*% +G54D12*X10000Y01000D02*X12000D01* +%SRX2Y2I3.0J6.0*% +G54D11*X10000Y00000D03* +G54D11*X10000Y01000D02*Y02000D01* +%SR*% +%SR*% +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep4.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep4.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep4.gbr (revision 818) @@ -0,0 +1,17 @@ +G04 leave drawing state in LPC at the end of a SR block and see how the next block starts: +G04 conclusion: states are SR-local * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.7000*% +%ADD12C,0.2000*% + +%LPD*% + +%SRX3Y2I3.0J6.0*% +G54D11*X10000Y01000D02*Y02000D01* +%LPC*% +G54D12*X10000Y01000D02*Y02000D01* +%SR*% + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep5.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep5.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep5.gbr (revision 818) @@ -0,0 +1,17 @@ +G04 leave drawing state in LPC before the SR block and see if it is inherited +G04 conclusion: SR-block states are inherited from parent * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.5000*% +%ADD12C,2.0000*% + +%LPD*% +G54D12*X10000Y01010D02*X60000D01* +%LPC*% +%SRX5Y1I3.0J0.0*% +G54D11*X10000Y01000D02*Y03000D01* +%SR*% +G54D11*X10000Y01010D02*X20000D01* + +M02* Index: tags/1.1.4/src_plugins/import_gerb/regression/steprep6.gbr =================================================================== --- tags/1.1.4/src_plugins/import_gerb/regression/steprep6.gbr (nonexistent) +++ tags/1.1.4/src_plugins/import_gerb/regression/steprep6.gbr (revision 818) @@ -0,0 +1,17 @@ +G04 test whether SR goes in x-y or y-x order, by checking overlaps * +G04 conclusion: inner loop should be y, from 0 up * +%MOMM*% +%FSLAX23Y23*% +%LNTOP*% +%ADD11C,0.7000*% +%ADD12C,0.3000*% + +%LPD*% + +%SRX3Y2I0.25J0.75*% +G54D11*X10000Y01000D02*Y02000D01* +%LPC*% +G54D12*X10000Y01000D02*Y02000D01* +%SR*% + +M02* Index: tags/1.1.4/src_plugins/io_tedax/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/io_tedax/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/Plug.tmpasm (revision 818) @@ -0,0 +1,11 @@ +put /local/rnd/mod {io_tedax} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/io_tedax/io_tedax.o + $(PLUGDIR)/io_tedax/parse.o +@] + +switch /local/module/io_tedax/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/io_tedax/a.tdx =================================================================== --- tags/1.1.4/src_plugins/io_tedax/a.tdx (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/a.tdx (revision 818) @@ -0,0 +1,27 @@ +tEDAx v1 + +begin camv_layer v1 big_blue_rect + color #0000ff + poly 5 5 60 5 60 60 5 60 +end camv_layer + +begin camv_grp v1 arrow1 + line 10 10 15 10 1 + line 15 10 13 8 1 + line 15 10 13 12 1 +end camv_grp + +begin camv_layer v1 pcb\ design\ errors + color #ff0000 + arc 14 11 3 0.5 -20 150 + + arc 40 40 10 0.2 0 33 + + poly 20 20 21 21 22 25 + unit mil + grp arrow1 + line 350 350 550 550 30 + polarity clear + line 350 340 550 560 5 +end camv_layer + Index: tags/1.1.4/src_plugins/io_tedax/io_tedax.c =================================================================== --- tags/1.1.4/src_plugins/io_tedax/io_tedax.c (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/io_tedax.c (revision 818) @@ -0,0 +1,600 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: camv-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include +#include + +#include +#include + +#include "camv_typedefs.h" +#include "plug_io.h" +#include "data.h" +#include +#include "parse.h" +#include +#include +#include +#include "obj_any.h" + +typedef struct { + camv_design_t *camv; + FILE *f; + char buf[514]; + char *argv[510]; + htsp_t grps; /* group name -> temporary layer */ + long lypos; +} read_ctx_t; + +#define coord_conv(dst, argnum, err) \ +do { \ + rnd_bool succ; \ + dst = rnd_get_value(argv[argnum], unit, NULL, &succ); \ + if (!succ) { \ + rnd_message(RND_MSG_ERROR, "invalid coordinate value\n"); \ + err; \ + } \ +} while(0) + +#define double_conv(dst, argnum, err) \ +do { \ + char *end; \ + dst = strtod(argv[argnum], &end); \ + if (*end != '\0') { \ + rnd_message(RND_MSG_ERROR, "invalid numeric value\n"); \ + err; \ + } \ +} while(0) + +static void copy_grp(read_ctx_t *ctx, camv_grp_t *dst, camv_layer_t *src) +{ + rnd_cardinal_t n; + camv_rtree_it_t it; + void *o; + + dst->len = src->objs.size; + dst->objs = malloc(sizeof(camv_any_obj_t) * dst->len); + + for(o = camv_rtree_all_first(&it, &src->objs), n = 0; o != NULL; o = camv_rtree_all_next(&it), n++) { + camv_any_obj_t *sobj = o; + assert(n < dst->len); + sobj->proto.calls->copy(&dst->objs[n], sobj); + } +} + +static int tdx_parse_layer(read_ctx_t *ctx, camv_layer_t *ly_main, rnd_bool is_grp) +{ + char **argv = ctx->argv; + int argc, poly_more = 0, res = 0; + char unit[8]; + int clearing = 0, has_color = 0; + camv_layer_t *ly = ly_main; + vtc0_t vert = {0}; + + strcpy(unit, "mm"); + + for(;;) { + if ((argc = tedax_getline(ctx->f, ctx->buf, sizeof(ctx->buf), ctx->argv, sizeof(ctx->argv) / sizeof(ctx->argv[0]))) < 0) + goto err; + + if (strcmp(argv[0], "end") == 0) { + if (!is_grp && (strcmp(argv[1], "camv_layer") == 0)) + return 0; + if (is_grp && (strcmp(argv[1], "camv_grp") == 0)) + return 0; + rnd_message(RND_MSG_ERROR, "invalid end tag\n"); + goto err; + } + + else if (strcmp(argv[0], "unit") == 0) { + if ((strcmp(argv[1], "m") == 0) || (strcmp(argv[1], "mm") == 0) || (strcmp(argv[1], "inch") == 0) || (strcmp(argv[1], "mil") == 0)) + strcpy(unit, argv[1]); + else { + rnd_message(RND_MSG_ERROR, "invalid unit\n"); + goto err; + } + } + + else if (strcmp(argv[0], "grp") == 0) { + camv_layer_t *gl; + camv_grp_t *grp; + + if (argc != 2) { + rnd_message(RND_MSG_ERROR, "invalid number of grp arguments\n"); + goto err; + } + gl = htsp_get(&ctx->grps, argv[1]); + if (gl == NULL) { + rnd_message(RND_MSG_ERROR, "group '%s' does not exist ref\n", argv[1]); + goto err; + } + grp = camv_grp_new(); + copy_grp(ctx, grp, gl); + camv_obj_add_to_layer(ly, (camv_any_obj_t *)grp); + } + + else if (strcmp(argv[0], "color") == 0) { + if (argc != 2) { + rnd_message(RND_MSG_ERROR, "invalid number of color arguments\n"); + goto err; + } + if (has_color) { + rnd_message(RND_MSG_ERROR, "only one color per layer can be set\n"); + goto err; + } + if (is_grp) { + rnd_message(RND_MSG_ERROR, "groups can not change color\n"); + goto err; + } + if (rnd_color_load_str(&ly->color, argv[1]) != 0) { + rnd_message(RND_MSG_ERROR, "invalid color string\n"); + goto err; + } + has_color = 1; + } + + else if (strcmp(argv[0], "polarity") == 0) { + int new_clearing; + if (argc != 2) { + rnd_message(RND_MSG_ERROR, "invalid number of polarity arguments\n"); + goto err; + } + if (is_grp) { + rnd_message(RND_MSG_ERROR, "groups can't change polarity\n"); + goto err; + } + if (strcmp(argv[1], "clear") == 0) new_clearing = 1; + else if (strcmp(argv[1], "draw") == 0) new_clearing = 0; + else { + rnd_message(RND_MSG_ERROR, "invalid polarity value\n"); + goto err; + } + if (!has_color) { + camv_layer_invent_color(ctx->camv, ly_main); + has_color = 1; + } + if (clearing != new_clearing) { + clearing = new_clearing; + ly = camv_layer_new(); + ly->sub = 1; + ly->clearing = clearing; + ly->color = ly_main->color; + ctx->lypos = camv_sublayer_append_after(ctx->camv, ly, ctx->lypos); + } + } + + else if (strcmp(argv[0], "line") == 0) { + rnd_coord_t x1, y1, x2, y2, th; + camv_line_t *line; + + if (argc != 6) { + rnd_message(RND_MSG_ERROR, "invalid number of line arguments\n"); + goto err; + } + coord_conv(x1, 1, return -1); + coord_conv(y1, 2, return -1); + coord_conv(x2, 3, return -1); + coord_conv(y2, 4, return -1); + coord_conv(th, 5, return -1); + line = camv_line_new(); + line->x1 = x1; line->y1 = y1; + line->x2 = x2; line->y2 = y2; + line->thick = th; + camv_obj_add_to_layer(ly, (camv_any_obj_t *)line); + } + + else if (strcmp(argv[0], "arc") == 0) { + rnd_coord_t cx, cy, r, th; + double start, delta; + camv_arc_t *arc; + + if (argc != 7) { + rnd_message(RND_MSG_ERROR, "invalid number of arc arguments\n"); + goto err; + } + coord_conv(cx, 1, return -1); + coord_conv(cy, 2, return -1); + coord_conv(r, 3, return -1); + coord_conv(th, 4, return -1); + double_conv(start, 5, return -1); + double_conv(delta, 6, return -1); + arc = camv_arc_new(); + arc->cx = cx; arc->cy = cy; arc->r = r; + arc->thick = th; + arc->start = start - 180; + arc->delta = -delta; + camv_obj_add_to_layer(ly, (camv_any_obj_t *)arc); + } + + else if (strcmp(argv[0], "poly") == 0) { + int i, n, numcrd; + + numcrd = argc-1; + if ((numcrd % 2) != 0) { + rnd_message(RND_MSG_ERROR, "need even number of coords in polygon\n"); + goto err; + } + + poly_more = 0; + for(n = 1, i = 0; n < argc; n += 2, i++) { + rnd_coord_t x, y; + if ((strcmp(argv[n], "more") == 0) && (strcmp(argv[n+1], "below") == 0)) { + poly_more = 1; + break; + } + coord_conv(x, n, goto poly_err); + coord_conv(y, n+1, goto poly_err); + vtc0_append(&vert, x); + vtc0_append(&vert, y); + } + + + if (!poly_more) { + camv_poly_t *poly; + if (vert.used < 6) { + rnd_message(RND_MSG_ERROR, "too few polygon coords\n"); + goto err; + } + + poly = camv_poly_new(); + camv_poly_allocpts(poly, vert.used/2); + for(n = 0, i = 0; n < vert.used; n += 2, i++) { + poly->x[i] = vert.array[n]; + poly->y[i] = vert.array[n+1]; + } + + camv_obj_add_to_layer(ly, (camv_any_obj_t *)poly); + vert.used = 0; + } + } + + else { + rnd_message(RND_MSG_ERROR, "Invalid tEDAx line: '%s'\n", argv[0]); + goto err; + } + } + + if (poly_more != 0) { + rnd_message(RND_MSG_ERROR, "unfinished polygon (last poly in layer ends in 'more below')\n"); + res = -1; + } + if (0) { + poly_err:; + rnd_message(RND_MSG_ERROR, "polygon coordinate conversion error\n"); + err:; + res = -1; + } + vtc0_uninit(&vert); + return res; +} + +int camv_tdx_load(camv_design_t *camv, const char *fn, FILE *f) +{ + read_ctx_t ctx; + camv_layer_t *ly; + int load_res = 0, found_one = 0; + rnd_cardinal_t first_new; + long n; /* must be signed */ + htsp_entry_t *e; + + ctx.camv = camv; + ctx.f = f; + + htsp_init(&ctx.grps, strhash, strkeyeq); + + while(tedax_seek_block(ctx.f, "camv_grp", "v1", NULL, 1, ctx.buf, sizeof(ctx.buf), ctx.argv, sizeof(ctx.argv)/sizeof(ctx.argv[0])) >= 0) { + if (htsp_has(&ctx.grps, ctx.argv[3])) { + rnd_message(RND_MSG_ERROR, "error: duplicate group: '%s'\n", ctx.argv[3]); + load_res = -1; + goto error; + } + ly = camv_layer_new(); + ly->name = rnd_strdup(ctx.argv[3]); + if (tdx_parse_layer(&ctx, ly, 1) != 0) { + load_res = -1; + goto error; + } + htsp_set(&ctx.grps, ly->name, ly); + } + + rewind(ctx.f); + + first_new = camv->layers.used; + while(tedax_seek_block(ctx.f, "camv_layer", "v1", NULL, 1, ctx.buf, sizeof(ctx.buf), ctx.argv, sizeof(ctx.argv)/sizeof(ctx.argv[0])) >= 0) { + found_one = 1; + ly = camv_layer_new(); + ly->name = rnd_strdup(ctx.argv[3]); + ctx.lypos = camv_layer_append_to_design(camv, ly); + if (tdx_parse_layer(&ctx, ly, 0) != 0) { + load_res = -1; + /* free all layers created by this load attempt */ + for(n = camv->layers.used - 1; n >= first_new; n--) + camv_layer_destroy(camv->layers.array[n]); + goto error; + } + } + + /* probably not a tedax file */ + if (!found_one) { + load_res = -1; + rnd_message(RND_MSG_ERROR, "error: no camv layer found in '%s'\n", fn); + } + + error:; + for(e = htsp_first(&ctx.grps); e != NULL; e = htsp_next(&ctx.grps, e)) + camv_layer_destroy(e->value); + htsp_uninit(&ctx.grps); + return load_res; +} + +/*** write ***/ + +typedef struct { + camv_design_t *camv; + FILE *f; + int err; +} write_ctx_t; + +static int tdx_open_write_header(camv_design_t *camv, write_ctx_t *ctx, const char *fn) +{ + rnd_printf_slot[4] = "%.06mm"; + ctx->camv = camv; + ctx->f = rnd_fopen((rnd_design_t *)ctx->camv, fn, "w"); + ctx->err = 0; + if (ctx->f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open '%s' for write\n", fn); + return -1; + } + fprintf(ctx->f, "tEDAx v1\n\n"); + return 0; +} + +static int tdx_close_write_header(write_ctx_t *ctx) +{ + fclose(ctx->f); + return ctx->err; +} + +static void tdx_write_obj(write_ctx_t *ctx, const camv_any_obj_t *obj) +{ + rnd_cardinal_t n; + int len; + + switch(obj->proto.type) { + case CAMV_OBJ_TEXT: break; /* shouldn't happen */ + case CAMV_OBJ_ARC: rnd_fprintf(ctx->f, "\tarc %[4] %[4] %[4] %[4] %f %f\n", obj->arc.cx, obj->arc.cy, obj->arc.r, obj->arc.thick, obj->arc.start+180, -obj->arc.delta); break; + case CAMV_OBJ_LINE: rnd_fprintf(ctx->f, "\tline %[4] %[4] %[4] %[4] %[4]\n", obj->line.x1, obj->line.y1, obj->line.x2, obj->line.y2, obj->line.thick); break; + case CAMV_OBJ_GRP: fprintf(ctx->f, "\tgrp %p\n", obj); break; + case CAMV_OBJ_POLY: + + for(len = n = 0; n < obj->poly.len; n++) { + if (len == 0) + len = fprintf(ctx->f, "\tpoly"); + len += rnd_fprintf(ctx->f, " %[4] %[4]", obj->poly.x[n], obj->poly.y[n]); + if (len > 480) { + if (n < obj->poly.len-1) + rnd_fprintf(ctx->f, " more below\n"); + len = 0; + } + } + fprintf(ctx->f, "\n"); + break; + case CAMV_OBJ_max: + case CAMV_OBJ_invalid: + assert(!"invalid object"); + break; + } +} + +static void tdx_write_grp(write_ctx_t *ctx, const camv_grp_t *grp) +{ + rnd_cardinal_t n; + fprintf(ctx->f, "begin camv_grp v1 %p\n", grp); + for(n = 0; n < grp->len; n++) { + assert(grp->objs[n].proto.type != CAMV_OBJ_GRP); /* do not allow group-in-group */ + tdx_write_obj(ctx, &grp->objs[n]); + } + fprintf(ctx->f, "end camv_grp\n\n"); +} + +static void tdx_write_layer_grps(write_ctx_t *ctx, const camv_layer_t *ly) +{ + void *o; + camv_rtree_it_t it; + + for(o = camv_rtree_all_first(&it, &ly->objs); o != NULL; o = camv_rtree_all_next(&it)) { + camv_any_obj_t *obj = o; + if (obj->proto.type != CAMV_OBJ_GRP) + continue; + tdx_write_grp(ctx, &obj->grp); + } +} + +static void tdx_write_layer_head(write_ctx_t *ctx, const camv_layer_t *ly) +{ + fprintf(ctx->f, "begin camv_layer v1 "); + tedax_fprint_escape(ctx->f, ly->name); + fprintf(ctx->f, "\n"); + fprintf(ctx->f, "\tcolor %s\n", ly->color.str); +} + +static void tdx_write_layer_foot(write_ctx_t *ctx, const camv_layer_t *ly) +{ + fprintf(ctx->f, "end camv_layer\n\n"); +} + +static void tdx_write_layer(write_ctx_t *ctx, const camv_layer_t *ly) +{ + void *o; + camv_rtree_it_t it; + + if (ly->clearing) + fprintf(ctx->f, "\tpolarity clear\n"); + else + fprintf(ctx->f, "\tpolarity draw\n"); + + for(o = camv_rtree_all_first(&it, &ly->objs); o != NULL; o = camv_rtree_all_next(&it)) + tdx_write_obj(ctx, o); +} + + +static int camv_tdx_save_sublayer(camv_design_t *camv, const camv_layer_t *ly, const char *fn) +{ + write_ctx_t ctx; + + if (tdx_open_write_header(camv, &ctx, fn) != 0) + return -1; + + tdx_write_layer_grps(&ctx, ly); + + tdx_write_layer_head(&ctx, ly); + tdx_write_layer(&ctx, ly); + tdx_write_layer_foot(&ctx, ly); + + return tdx_close_write_header(&ctx); +} + + +static int camv_tdx_save_layer(camv_design_t *camv, rnd_cardinal_t lid, const char *fn) +{ + write_ctx_t ctx; + rnd_cardinal_t n; + const camv_layer_t *ly; + + if (tdx_open_write_header(camv, &ctx, fn) != 0) + return -1; + + for(n = lid; n < camv->layers.used; n++) { + ly = camv->layers.array[n]; + if ((n > lid) && (!ly->sub)) break; + tdx_write_layer_grps(&ctx, ly); + } + + ly = camv->layers.array[lid]; + tdx_write_layer_head(&ctx, ly); + for(n = lid; n < camv->layers.used; n++) { + ly = camv->layers.array[n]; + if ((n > lid) && (!ly->sub)) break; + + tdx_write_layer(&ctx, ly); + } + tdx_write_layer_foot(&ctx, ly); + + return tdx_close_write_header(&ctx); +} + + +static int camv_tdx_save_design(camv_design_t *camv, const char *fn) +{ + write_ctx_t ctx; + long n, end, i; + int open_ly = 0; + const camv_layer_t *ly; + + if (tdx_open_write_header(camv, &ctx, fn) != 0) + return -1; + + for(n = 0; n < camv->layers.used; n++) + tdx_write_layer_grps(&ctx, camv->layers.array[n]); + + /* write layers in reverse order so the file is top->bottom */ + end = camv->layers.used; + for(n = camv->layers.used-1; n >= 0; n--) { + ly = camv->layers.array[n]; + if (!ly->sub) { + if (open_ly) + tdx_write_layer_foot(&ctx, ly); + tdx_write_layer_head(&ctx, ly); + open_ly = 1; + for(i = n; i < end; i++) + tdx_write_layer(&ctx, camv->layers.array[i]); + end = n; + } + } + + if (open_ly) + tdx_write_layer_foot(&ctx, ly); + + return tdx_close_write_header(&ctx); +} + +static int camv_tdx_test_load(camv_design_t *camv, const char *fn, FILE *f) +{ + char *line, line_[1024]; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + while(isspace(*line)) line++; + if (*line == '#') + continue; + + if (strncmp(line, "tEDAx", 5) != 0) + return 0; + line += 5; + while(isspace(*line)) line++; + if (strncmp(line, "v1", 2) != 0) + return 0; + if (isalnum(line[2])) + return 0; + return 1; + } + return 0; +} + +static int camv_tdx_save_prio(const char *fn, const char *fmt, camv_io_type_t type) +{ + if ((type & CSCH_IOTYP_DESIGN) == 0) + return -1; + + if ((rnd_strcasecmp(fmt, "tdx") != 0) && (rnd_strcasecmp(fmt, "tedax") != 0)) + return -1; + + return 100; +} + +static camv_io_t io_tdx = { + "tEDAx camv layer", 100, + camv_tdx_test_load, + camv_tdx_load, + camv_tdx_save_prio, + camv_tdx_save_design, + "tdx" +}; + + +int pplg_check_ver_io_tedax(int ver_needed) { return 0; } + +void pplg_uninit_io_tedax(void) +{ + camv_io_unreg(&io_tdx); +} + +int pplg_init_io_tedax(void) +{ + camv_io_reg(&io_tdx); + return 0; +} Index: tags/1.1.4/src_plugins/io_tedax/io_tedax.pup =================================================================== --- tags/1.1.4/src_plugins/io_tedax/io_tedax.pup (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/io_tedax.pup (revision 818) @@ -0,0 +1,10 @@ +$class io +$short native tEDAx layer format +$long Load and save camv layers in tEDAx +$package (core) +$state works +$fmt-native yes +$fmt-feature-r tEDAx camv-rnd layer +$fmt-feature-w tEDAx camv-rnd layer +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/io_tedax/parse.c =================================================================== --- tags/1.1.4/src_plugins/io_tedax/parse.c (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/parse.c (revision 818) @@ -0,0 +1,186 @@ +/* + * COPYRIGHT + * + * camv-rnd - electronics-related CAM viewer + * (originally copier from pcb-rnd) + * + * tedax IO plugin - low level parser, similar to the reference implementation + * pcb-rnd Copyright (C) 2017 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/camv-rnd + * lead developer: http://repo.hu/projects/camv-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +#include + +#include "parse.h" +#include +#include + +int tedax_getline(FILE *f, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc; + + for(;;) { + char *s, *o; + + if (fgets(buff, buff_size, f) == NULL) + return -1; + + s = buff; + if (*s == '#') /* comment */ + continue; + ltrim(s); + rtrim(s); + if (*s == '\0') /* empty line */ + continue; + + /* argv split */ + for(argc = 0, o = argv[0] = s; *s != '\0';) { + if (*s == '\\') { + s++; + switch(*s) { + case 'r': *o = '\r'; break; + case 'n': *o = '\n'; break; + case 't': *o = '\t'; break; + default: *o = *s; + } + o++; + s++; + continue; + } + if ((argc+1 < argv_size) && ((*s == ' ') || (*s == '\t'))) { + *o = *s = '\0'; + s++; + o++; + while((*s == ' ') || (*s == '\t')) + s++; + argc++; + argv[argc] = o; + } + else { + *o = *s; + s++; + o++; + } + } + *o = '\0'; + return argc+1; /* valid line, split up */ + } + + return -1; /* can't get here */ +} + +int tedax_seek_hdr(FILE *f, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc; + + /* look for the header */ + if ((argc = tedax_getline(f, buff, buff_size, argv, argv_size)) < 2) { + rnd_message(RND_MSG_ERROR, "Can't find tEDAx header (no line)\n"); + return -1; + } + + if ((argv[1] == NULL) || (rnd_strcasecmp(argv[0], "tEDAx") != 0) || (rnd_strcasecmp(argv[1], "v1") != 0)) { + rnd_message(RND_MSG_ERROR, "Can't find tEDAx header (wrong line)\n"); + return -1; + } + + return argc; +} + + +int tedax_seek_block(FILE *f, const char *blk_name, const char *blk_ver, const char *blk_id, int silent, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc; + + /* seek block begin */ + while((argc = tedax_getline(f, buff, buff_size, argv, argv_size)) >= 0) + if ((argc > 2) && (strcmp(argv[0], "begin") == 0) && (strcmp(argv[1], blk_name) == 0) && ((blk_ver == NULL) || (strcmp(argv[2], blk_ver) == 0)) && ((blk_id == NULL) || (strcmp(argv[3], blk_id) == 0))) + break; + + if (argc < 2) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Can't find %s %s block in tEDAx\n", blk_ver, blk_name); + return -1; + } + + return argc; +} + +void tedax_fprint_escape(FILE *f, const char *val) +{ + if ((val == NULL) || (*val == '\0')) { + fputc('-', f); + return; + } + for(; *val != '\0'; val++) { + switch(*val) { + case '\\': fputc('\\', f); fputc('\\', f); break; + case '\n': fputc('\\', f); fputc('n', f); break; + case '\r': fputc('\\', f); fputc('r', f); break; + case '\t': fputc('\\', f); fputc('t', f); break; + case ' ': fputc('\\', f); fputc(' ', f); break; + default: + fputc(*val, f); + } + } +} + +#define APPEND(c) \ + do { \ + if (dstlen == 0) { \ + res = -1; \ + goto quit; \ + } \ + *d = c; \ + d++; \ + dstlen--; \ + } while(0) + +int tedax_strncpy_escape(char *dst, int dstlen, const char *val) +{ + int res = 0; + char *d = dst; + + assert(dstlen > 2); + if ((val == NULL) || (*val == '\0')) { + dst[0] = '-'; + dst[1] = '\0'; + return 0; + } + dstlen--; /* one for \0 */ + for(; *val != '\0'; val++) { + switch(*val) { + case '\\': APPEND('\\'); APPEND('\\'); break; + case '\n': APPEND('\\'); APPEND('n'); break; + case '\r': APPEND('\\'); APPEND('r'); break; + case '\t': APPEND('\\'); APPEND('t'); break; + case ' ': APPEND('\\'); APPEND(' '); break; + default: + APPEND(*val); + } + } + quit:; + *d = '\0'; + return res; +} + Index: tags/1.1.4/src_plugins/io_tedax/parse.h =================================================================== --- tags/1.1.4/src_plugins/io_tedax/parse.h (nonexistent) +++ tags/1.1.4/src_plugins/io_tedax/parse.h (revision 818) @@ -0,0 +1,29 @@ +#include +#include +#include + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline;; trailing backslash is an error */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + if (*end == '\\') \ + return -1; \ + } while(0) + +#define null_empty(s) ((s) == NULL ? "" : (s)) + +int tedax_getline(FILE *f, char *buff, int buff_size, char *argv[], int argv_size); + +int tedax_seek_hdr(FILE *f, char *buff, int buff_size, char *argv[], int argv_size); +int tedax_seek_block(FILE *f, const char *blk_name, const char *blk_ver, const char *blk_id, int silent, char *buff, int buff_size, char *argv[], int argv_size); + + +/* print val with special chars escaped. Prints a single dash if val is NULL or empty. */ +void tedax_fprint_escape(FILE *f, const char *val); +int tedax_strncpy_escape(char *dst, int dstlen, const char *val); + Index: tags/1.1.4/src_plugins/map_plugins.sh =================================================================== --- tags/1.1.4/src_plugins/map_plugins.sh (nonexistent) +++ tags/1.1.4/src_plugins/map_plugins.sh (revision 818) @@ -0,0 +1,60 @@ +#!/bin/sh + +# Run this script after changing or adding .pup files. +# WARNING: this script requires a fair amount of tools - it is intended to +# run on developers' machines, not on users' + +. ../config.sh + +export LANG=C +PUPLUG=$librnd_libdir/puplug +SCCONF=../scconfig + + +# generate scconfig's 3 state plugin list +$PUPLUG findpups . '%$class$|%N|%3|%A|%$short$\n' | sed ' +s/^lib/1|lib/ +s/^feature/2|feature/ +s/^import/3|import/ +s/^export/4|export/ +s/^io/5|io/ +s/^hid/6|hid/ +s/^gui/6|gui/ +' | sort | awk -F "[|]" ' +BEGIN { + HDR["lib"] = "Library plugins" + HDR["feature"] = "Feature plugins" + HDR["import"] = "Import plugins" + HDR["export"] = "Export plugins" + HDR["io"] = "IO plugins (file formats)" + HDR["gui"] = "GUI" + print "/******************************************************************************" + print " Auto-generated by plugins/map_plugins.sh - do NOT edit," + print " run make map_plugins in sch-rnd/ - to change any of the data below," + print " edit plugins/PLUGIN/PLUGIN.pup" + print "******************************************************************************/" +} + +function q(s) { return "\"" s "\"," } + +($2 != last) { + print "\nplugin_header(\"\\n" HDR[$2] ":\\n\")" + last = $2 +} + +{ + if ($4 == "") + print "Error: invalid default in plugin: " $3 > "/dev/stderr" + printf("plugin_def(%-20s%-35s%-10s%s)\n", q($3), q($6), $4 "," , $5) +} + +END { print "\n" } + +' > $SCCONF/plugins.h + +$PUPLUG findpups . "" 'plugin_dep("%N", "%m")\n' | sort >> $SCCONF/plugins.h + + +# Generate the plugin list +echo "# List of all plugins - generated by make map_plugins - do NOT edit" > plugins_ALL.tmpasm +$PUPLUG findpups . "include {../src_plugins/%D/Plug.tmpasm}\n" | sort >> plugins_ALL.tmpasm Property changes on: tags/1.1.4/src_plugins/map_plugins.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/src_plugins/plugins_ALL.tmpasm =================================================================== --- tags/1.1.4/src_plugins/plugins_ALL.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/plugins_ALL.tmpasm (revision 818) @@ -0,0 +1,12 @@ +# List of all plugins - generated by make map_plugins - do NOT edit +include {../src_plugins/dialogs/Plug.tmpasm} +include {../src_plugins/export_lpr/Plug.tmpasm} +include {../src_plugins/export_png/Plug.tmpasm} +include {../src_plugins/export_ps/Plug.tmpasm} +include {../src_plugins/export_svg/Plug.tmpasm} +include {../src_plugins/gui/Plug.tmpasm} +include {../src_plugins/import_excellon/Plug.tmpasm} +include {../src_plugins/import_gcode/Plug.tmpasm} +include {../src_plugins/import_gerb/Plug.tmpasm} +include {../src_plugins/io_tedax/Plug.tmpasm} +include {../src_plugins/std_tools/Plug.tmpasm} Index: tags/1.1.4/src_plugins/std_tools/Makefile =================================================================== --- tags/1.1.4/src_plugins/std_tools/Makefile (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/Makefile (revision 818) @@ -0,0 +1,2 @@ +all: + cd ../../src && make Index: tags/1.1.4/src_plugins/std_tools/Plug.tmpasm =================================================================== --- tags/1.1.4/src_plugins/std_tools/Plug.tmpasm (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/Plug.tmpasm (revision 818) @@ -0,0 +1,10 @@ +put /local/rnd/mod {std_tools} +put /local/rnd/mod/OBJS [@ + $(PLUGDIR)/std_tools/std_tools.o +@] + +switch /local/module/std_tools/controls + case {buildin} include /local/camv/tmpasm/buildin; end; + case {plugin} include /local/camv/tmpasm/plugin; end; + case {disable} include /local/camv/tmpasm/disable; end; +end Index: tags/1.1.4/src_plugins/std_tools/std_tools.c =================================================================== --- tags/1.1.4/src_plugins/std_tools/std_tools.c (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/std_tools.c (revision 818) @@ -0,0 +1,29 @@ + +#include + +#include + +#include +#include +#include + +static const char std_tools_cookie[] = "std_tools"; + +#include "tool_mline.c" +#include "tool_mobj.c" +#include "tool_arrow.c" + +int pplg_check_ver_std_tools(int ver_needed) { return 0; } + +void pplg_uninit_std_tools(void) +{ +} + +int pplg_init_std_tools(void) +{ + rnd_tool_reg(&camv_rnd_tool_arrow, std_tools_cookie); + rnd_tool_reg(&camv_rnd_tool_mline, std_tools_cookie); + rnd_tool_reg(&camv_rnd_tool_mobj, std_tools_cookie); + + return 0; +} Index: tags/1.1.4/src_plugins/std_tools/std_tools.pup =================================================================== --- tags/1.1.4/src_plugins/std_tools/std_tools.pup (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/std_tools.pup (revision 818) @@ -0,0 +1,7 @@ +$class io +$short standard drawing tools +$long Tools for drawing standard cschem concrete primitives +$state WIP +$package (core) +default buildin +autoload 1 Index: tags/1.1.4/src_plugins/std_tools/tool_arrow.c =================================================================== --- tags/1.1.4/src_plugins/std_tools/tool_arrow.c (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/tool_arrow.c (revision 818) @@ -0,0 +1,85 @@ +#include "crosshair.h" +#include "data.h" +#include +#include + +static void tool_arrow_init(void) +{ +} + +static void tool_arrow_uninit(void) +{ +} + +static void tool_arrow_press(rnd_design_t *hl) +{ +} + +static void tool_arrow_release(rnd_design_t *hl) +{ +} + +static void tool_arrow_adjust_attached_objects(rnd_design_t *hl) +{ +} + + +static void tool_arrow_draw_attached(rnd_design_t *hl) +{ +} + +rnd_bool tool_arrow_undo_act(rnd_design_t *hl) +{ + return 0; +} + +rnd_bool tool_arrow_redo_act(rnd_design_t *hl) +{ + return 0; +} + + + +/* XPM */ +static const char *arrow_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"oo .. ooooooooooooooo", +"oo .... ooooooooooooo", +"ooo ...... oooooooooo", +"ooo ........ oooooooo", +"ooo ....... ooooooooo", +"oooo ..... oooooooooo", +"oooo ...... ooooooooo", +"ooooo .. ... oooooooo", +"ooooo . o ... ooooooo", +"oooooooooo ... oooooo", +"ooooooooooo .. oooooo", +"oooooooooooo ooooooo", +"ooooooooooooooooooooo", +"ooo ooo ooo ooo", +"oo o oo ooo oo ooo oo", +"oo o oo ooo oo ooo oo", +"o ooo o ooo ooo", +"o ooo o ooo oo ooo oo", +"o o ooo oo ooo oo", +"o ooo o ooo oo ooo oo", +"o ooo o ooo oo ooo oo" +}; + + +static rnd_tool_t camv_rnd_tool_arrow = { + "arrow", NULL, std_tools_cookie, 50, arrow_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + tool_arrow_init, + tool_arrow_uninit, + tool_arrow_press, + tool_arrow_release, + tool_arrow_adjust_attached_objects, + tool_arrow_draw_attached, + tool_arrow_undo_act, + tool_arrow_redo_act +}; Index: tags/1.1.4/src_plugins/std_tools/tool_mline.c =================================================================== --- tags/1.1.4/src_plugins/std_tools/tool_mline.c (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/tool_mline.c (revision 818) @@ -0,0 +1,146 @@ + +#include "tool_mline.h" + +#include "crosshair.h" +#include "data.h" +#include "obj_any.h" +#include "obj_line.h" +#include "obj_text.h" +#include +#include +#include +#include +#include + +camv_tool_mline_t camv_tool_mline; + +static void create_mline(rnd_design_t *hl) +{ + camv_any_obj_t *o; + camv_design_t *camv = (camv_design_t *)hl; + camv_layer_t *ly = camv_layer_by_name(camv, camv_measurement_layer_name, 1); + double dist = rnd_distance(camv_tool_mline.x1, camv_tool_mline.y1, camv_tool_mline.x2, camv_tool_mline.y2); + + o = (camv_any_obj_t *)camv_line_new(); + o->line.x1 = camv_tool_mline.x1; o->line.y1 = camv_tool_mline.y1; + o->line.x2 = camv_tool_mline.x2; o->line.y2 = camv_tool_mline.y2; + o->line.thick = 1; + camv_obj_add_to_layer(ly, o); + + o = (camv_any_obj_t *)camv_text_new(); + o->text.x = (camv_tool_mline.x1 + camv_tool_mline.x2) / 2; + o->text.y = (camv_tool_mline.y1 + camv_tool_mline.y2) / 2; + o->text.rot = atan2(camv_tool_mline.y2 - camv_tool_mline.y1, camv_tool_mline.x2 - camv_tool_mline.x1) * RND_RAD_TO_DEG; + o->text.s = rnd_strdup_printf("%m+%.03$$mS", rnd_conf.editor.grid_unit->allow, (rnd_coord_t)dist); + + camv_text_update(hl, &o->text, ly); + camv_obj_add_to_layer(ly, o); +} + +static void tool_mline_init(void) +{ +} + +static void tool_mline_uninit(void) +{ +} + +static void tool_mline_press(rnd_design_t *hl) +{ +} + +static void tool_mline_release(rnd_design_t *hl) +{ + switch(camv_tool_mline.clicked) { + case 0: + camv_tool_mline.x1 = camv_tool_mline.x2 = camv.crosshair_x; + camv_tool_mline.y1 = camv_tool_mline.y2 = camv.crosshair_y; + camv_tool_mline.clicked = 1; + break; + case 1: + camv_tool_mline.x2 = camv.crosshair_x; + camv_tool_mline.y2 = camv.crosshair_y; + create_mline(hl); + camv_tool_mline.clicked = 0; + break; + } +} + +static void tool_mline_adjust_attached_objects(rnd_design_t *hl) +{ + if (camv_tool_mline.clicked == 1) { + camv_tool_mline.x2 = camv.crosshair_x; + camv_tool_mline.y2 = camv.crosshair_y; + } +} + + +static void tool_mline_draw_attached(rnd_design_t *hl) +{ + rnd_hid_set_line_cap(camv_crosshair_gc, rnd_cap_round); + rnd_hid_set_line_width(camv_crosshair_gc, -1); + + switch(camv_tool_mline.clicked) { + case 0: break; + case 1: + rnd_render->draw_line(camv_crosshair_gc, camv_tool_mline.x1, camv_tool_mline.y1, camv_tool_mline.x2, camv_tool_mline.y2); + break; + } +} + +rnd_bool tool_mline_undo_act(rnd_design_t *hl) +{ + return 0; +} + +rnd_bool tool_mline_redo_act(rnd_design_t *hl) +{ + return 0; +} + + + +/* XPM */ +static const char *mline_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOO.OOOOOOOOOOOOOOOO", +"OOOO.OOOOOOOOOOOOOOOO", +"OOO.OOOOOOOOOOOOOOOOO", +"OOO.XXOOOOOOOOOOOOOOO", +"OOO.OOXXXOOOOOOOOO.OO", +"OO.OOOOOOXXXOOOOOO.OO", +"OO.OOOOOOOOOXXXOO.OOO", +"OOOOOOOOOOOOOOOXX.OOO", +"OOOOOOOOOOOOOOOOO.OOO", +"OOOOOOOOOOOOOOOO.OOOO", +"OOOOOOOOOOOOOOOO.OOOO", +"OOOOOOOOOOOOOOOOOOOOO", +"O OOO O OOO O OOO O", +"O O O OOOO OO OO O", +"O O O O OOOO OO OO O", +"O OOO O OOOO OO O O O", +"O OOO O OOOO OO O O O", +"O OOO O OOOO OO OO O", +"O OOO O OOOO OO OO O", +"O OOO O O O OOO O", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t camv_rnd_tool_mline = { + "mline", NULL, std_tools_cookie, 100, mline_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0, + tool_mline_init, + tool_mline_uninit, + tool_mline_press, + tool_mline_release, + tool_mline_adjust_attached_objects, + tool_mline_draw_attached, + tool_mline_undo_act, + tool_mline_redo_act +}; Index: tags/1.1.4/src_plugins/std_tools/tool_mline.h =================================================================== --- tags/1.1.4/src_plugins/std_tools/tool_mline.h (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/tool_mline.h (revision 818) @@ -0,0 +1,13 @@ +#ifndef CAMV_TOOL_MLINE +#define CAMV_TOOL_MLINE 1 + +#include + +typedef struct { + /* statates */ + rnd_coord_t x1, y1, x2, y2; + int clicked; /* 0 means waiting for x1,y1, 1 means waiting for x2,y2 */ + int valid; /* there is an active attached object line */ +} camv_tool_mline_t; + +#endif Index: tags/1.1.4/src_plugins/std_tools/tool_mobj.c =================================================================== --- tags/1.1.4/src_plugins/std_tools/tool_mobj.c (nonexistent) +++ tags/1.1.4/src_plugins/std_tools/tool_mobj.c (revision 818) @@ -0,0 +1,132 @@ +#include "crosshair.h" +#include "data.h" +#include +#include +#include + +static void tool_mobj_init(void) +{ +} + +static void tool_mobj_uninit(void) +{ +} + +static void tool_mobj_press(rnd_design_t *hl) +{ + long lid; + rnd_coord_t slop = rnd_gui->coord_per_pix * 3 / 2; + camv_rtree_box_t sb; + + sb.x1 = camv.crosshair_x - slop; + sb.y1 = camv.crosshair_y - slop; + sb.x2 = camv.crosshair_x + slop; + sb.y2 = camv.crosshair_y + slop; + + for(lid = camv.layers.used-1; lid >= 0; lid--) { + camv_rtree_it_t it; + camv_layer_t *ly = camv.layers.array[lid]; + camv_any_obj_t *obj = camv_rtree_first(&it, &ly->objs, &sb); + if ((obj != NULL) && (obj->proto.calls->isc_box(obj, &sb))) { + rnd_message(RND_MSG_WARNING, "%s ", ly->name, obj->proto.type); + switch(obj->proto.type) { + case CAMV_OBJ_ARC: + rnd_message(RND_MSG_WARNING, "Arc: center %m+%$mD radius=%$mN\n thickness=%$mN\n", + rnd_conf.editor.grid_unit->allow, + obj->arc.cx, obj->arc.cy, obj->arc.r, + obj->line.thick); + break; + case CAMV_OBJ_LINE: + rnd_message(RND_MSG_WARNING, "Line: %m+%$mD to %$mD\n length=%$mN thickness=%$mN\n", + rnd_conf.editor.grid_unit->allow, + obj->line.x1, obj->line.y1, obj->line.x2, obj->line.y2, + (rnd_coord_t)rnd_distance(obj->line.x1, obj->line.y1, obj->line.x2, obj->line.y2), + obj->line.thick); + break; + case CAMV_OBJ_POLY: + rnd_message(RND_MSG_WARNING, "Polygon\n"); + break; + case CAMV_OBJ_GRP: + rnd_message(RND_MSG_WARNING, "Group\n"); + break; + case CAMV_OBJ_TEXT: + rnd_message(RND_MSG_WARNING, "Text\n"); + break; + case CAMV_OBJ_invalid: + case CAMV_OBJ_max: + rnd_message(RND_MSG_WARNING, "\n"); + break; + } + } + } +} + +static void tool_mobj_release(rnd_design_t *hl) +{ +} + +static void tool_mobj_adjust_attached_objects(rnd_design_t *hl) +{ +} + + +static void tool_mobj_draw_attached(rnd_design_t *hl) +{ +} + +rnd_bool tool_mobj_undo_act(rnd_design_t *hl) +{ + return 0; +} + +rnd_bool tool_mobj_redo_act(rnd_design_t *hl) +{ + return 0; +} + + + +/* XPM */ +static const char *mobj_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOO..OOOOOOOOOO", +"OOOOOOOO....OOOOOOOOO", +"OOOOOOO..OO..OOOOOOOO", +"OOOOOOO..OO..OOOOOOOO", +"OOOOOOOX....XOOOOOOOO", +"OOOOOOOXO..OXOOOOOOOO", +"OOOOOOOXOOOOXOOOOOOOO", +"OOOOOOOXOOOOXOOOOOOOO", +"OOOOOOOXXXXXXOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +"O OOO OO OO OOO O", +"O O O OO O OO OOO O", +"O O O O OO O OO OOO O", +"O OOO O OO O OOO O", +"O OOO O OO O OO OOO O", +"O OOO O OO O OO OOO O", +"O OOO O OO O OO O O O", +"O OOO OO OO OO OO", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +static rnd_tool_t camv_rnd_tool_mobj = { + "mobj", NULL, std_tools_cookie, 100, mobj_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0, + tool_mobj_init, + tool_mobj_uninit, + tool_mobj_press, + tool_mobj_release, + tool_mobj_adjust_attached_objects, + tool_mobj_draw_attached, + tool_mobj_undo_act, + tool_mobj_redo_act +}; Index: tags/1.1.4/util/sign/crl_repo.hu.pem =================================================================== --- tags/1.1.4/util/sign/crl_repo.hu.pem (nonexistent) +++ tags/1.1.4/util/sign/crl_repo.hu.pem (revision 818) @@ -0,0 +1,19 @@ +-----BEGIN X509 CRL----- +MIIDGzCCAQMwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAkhVMREwDwYDVQQI +EwhCdWRhcGVzdDERMA8GA1UEBxMIQnVkYXBlc3QxEDAOBgNVBAoTB3JlcG8uaHUx +DjAMBgNVBAsTBUlnb3IyMRMwEQYDVQQDEwpyZXBvLmh1IENBMSwwKgYDVQQpEyNy +ZXBvLmh1IHB1YmxpYyBzc2wgYW5kIGZpbGUgc2lnbmluZzEjMCEGCSqGSIb3DQEJ +ARYUa2V5aW5nQGlnb3IyLnJlcG8uaHUXDTIzMTAxMTEwNTA0OFoXDTI0MTEwOTEw +NTA0OFowFDASAgEBFw0yMDA0MjExNTM5NDNaMA0GCSqGSIb3DQEBCwUAA4ICAQC6 +au6OTwfJ/F4XEyY/6mKHm6o2ri5YJ/2TpRa9hl2HFDlOvw6IiD9cxArVj+Vbgf52 +QJtJY3WeMR1omJ9MBiVFNzaeUuj6WbBnNGEtkrAQTawxjgJ7hzPuh/bKSoSnr22P +gT0hkfRjBqNv4ZBy9oVFgixBU3VYj5vEgc0g0kydqJfCvxX1IdaBPtYq7vK6CHou +2pIB/AQIRNrvde1nfm4tAvq/Zdiv4ToYMFyQqtH7qaigchMPhoU/tAurTocJ5ssS +UtURiR0jsjst/TIBCv1yGr+NTutT/ZxWFb0nYYW4egC6lGoJGRx/Kko0P6zbwqUj +Ocje+s816xqBgDW2Twl00YvqyfG54OA8lw1LW8gwndVbk1HyxoReXgrYr7jIoo7a +vua739FPy3ElC3VchdfusomqPHUsl4egYOG/bwHlnYAEhXFjtYgVt1IGuI0QGwCx +lEcYAnKpTU3roTGyZJbMAbtcln57+e2Oz7c48ZcvA6/RgEp3Y8Kdc3RTz31Tq/jN +wYDpD4GrrQK9nZk1057B8Yzg82Jyv00qN4hBJxdoae9OFS17iar+A44bY+NEikzG ++iife5pp9kZbg0/Xh5MECEUcPKeaiNGJRvs4E8j/8xJeASqtrCOHfEjLicG6VIc3 +Lz8Qd1Je/jbPn/9RrJKinL4nsXz62h25WBRSSOrrhw== +-----END X509 CRL----- Index: tags/1.1.4/util/sign/rootca_repo.hu_2020.crt =================================================================== --- tags/1.1.4/util/sign/rootca_repo.hu_2020.crt (nonexistent) +++ tags/1.1.4/util/sign/rootca_repo.hu_2020.crt (revision 818) @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHJzCCBQ+gAwIBAgIJAOOTjzdHBDWkMA0GCSqGSIb3DQEBCwUAMIG9MQswCQYD +VQQGEwJIVTERMA8GA1UECBMIQnVkYXBlc3QxETAPBgNVBAcTCEJ1ZGFwZXN0MRAw +DgYDVQQKEwdyZXBvLmh1MQ4wDAYDVQQLEwVJZ29yMjETMBEGA1UEAxMKcmVwby5o +dSBDQTEsMCoGA1UEKRMjcmVwby5odSBwdWJsaWMgc3NsIGFuZCBmaWxlIHNpZ25p +bmcxIzAhBgkqhkiG9w0BCQEWFGtleWluZ0BpZ29yMi5yZXBvLmh1MB4XDTIwMDQy +MTEyMjYwNVoXDTMwMDQxOTEyMjYwNVowgb0xCzAJBgNVBAYTAkhVMREwDwYDVQQI +EwhCdWRhcGVzdDERMA8GA1UEBxMIQnVkYXBlc3QxEDAOBgNVBAoTB3JlcG8uaHUx +DjAMBgNVBAsTBUlnb3IyMRMwEQYDVQQDEwpyZXBvLmh1IENBMSwwKgYDVQQpEyNy +ZXBvLmh1IHB1YmxpYyBzc2wgYW5kIGZpbGUgc2lnbmluZzEjMCEGCSqGSIb3DQEJ +ARYUa2V5aW5nQGlnb3IyLnJlcG8uaHUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDXBFlluNaF/Pikec4TeEq/UsZAg1XhhmUJZnzAx7i84ramW0rvvdxN +bdWAAjuaQG7qRSnZNQieDcHKq/xeAz3TMxmXGytclOh7HtXaTbg963dQd4sZ7wK+ +Nv1znTJSR5jx6u5ijiaKqktVRiRndUsWw/pKSZvEY8uCc+4vK0xzPM49cYMOG0VV +Vs3IT47piONWbuCqXgi+ijHFHpPKLW2x4jDP6OXhXHWMg2J8+q/ggqURpUscNnvP +NfIPGyr7ZRsVVrTRNHA1clYDJFbHrkqhcjSodWvEmAbmz31DfYrlxnDVEmYqOqxO +K6y2cn0rYUbuM8yc1hO4MgncXZ1y+3SoFK/LvsPR1MlGeqMRBL4Ru/S7q8/NEak8 ++gPYJiIdy5Pt9hzZv1C7cPlsxXS1xCHJOk2xNbDrUuDV98P0ZYYY/7K98fss43vZ +UzbR/+eVhrjESFiHY/7Gcknaa9d0RMzSNWik/cBUwDty1C9OdxqeOmWE/uRqsViF +6ypxRG9ZRJnuqWxa8+PT3EFJLARizz06uzD0nN0xqMI1k3s5hXDDSloH8eK4UF2j +ZtHLo0m/4b6l3dZmkG5/eJAq2Kg8r6Bzx9oAnRUW8MPjJL95XrDClWAVrABTWs0E +409AklGh8w4+hB2xD8ZbNXDMyu1S+ic1CzYPMa9a3NPsrG1/H9A2WwIDAQABo4IB +JjCCASIwHQYDVR0OBBYEFOxDrX4j1c5ZbQdhCaRmlzxEAKx5MIHyBgNVHSMEgeow +geeAFOxDrX4j1c5ZbQdhCaRmlzxEAKx5oYHDpIHAMIG9MQswCQYDVQQGEwJIVTER +MA8GA1UECBMIQnVkYXBlc3QxETAPBgNVBAcTCEJ1ZGFwZXN0MRAwDgYDVQQKEwdy +ZXBvLmh1MQ4wDAYDVQQLEwVJZ29yMjETMBEGA1UEAxMKcmVwby5odSBDQTEsMCoG +A1UEKRMjcmVwby5odSBwdWJsaWMgc3NsIGFuZCBmaWxlIHNpZ25pbmcxIzAhBgkq +hkiG9w0BCQEWFGtleWluZ0BpZ29yMi5yZXBvLmh1ggkA45OPN0cENaQwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAJz/MUVFBYvWto1iDHYFQWz2hRitx +AKtphsKtUF0fZ4mwZ/GN8/gItKaEndkFVQt250/ZlDqNOsR0WUwxHUuvKQnZj3yK +QPWqJf4XAiXWD4UHm+xjIKub6K5SgrWKDF+2pM0vWHv80vinpwKCmn1qlFRY9hZY +Cr40yGATb9Ebr5mO3Q+Xacj/EmPxogjPd0IkoC2sHnlaXIkDtD4sZtqQyJc1h1fQ +xfxYh/w3kURTps856Y8wlvpc2R4B592sTf4p78Jv+tQxm400HNE4NNyNUwmHvQ9p +gRW/HWBVy/vjGhYz4645VBwFQ7bt0qLFaEOQBxOHYY+J8uneH8vMGtJduS0gyHvb +Qv/rOS71gPau2niTLH7CbKtqdG1RY1O6npjAxLIKsO5QJN1BN5svg8M6bIvY4KJZ +n3f1ISJQTIUvyu+A2gOe2459qf1Bn3zalYVPWmDqBLkqnR1mnCEhOYuNR1ES05xx +tJWzfQSerBJWQqTZ430E3zwapFVWCOky5H89xFPXBiodWfOzpdenAHBaoSqjG6fM +tqJ0umljL+Xn6EzaHsAjEkJFTK4TZ71SAFugRNRrXlX9+efZmTHpNDXzZ1gs5j71 +o1IQ9wl2eSopft8NU0nbefnfQ1+QcEAqM9z9BM3u0I2kX7ddPI7KzGCqq3nxrP6c +C7BZ2G6M6Jr7pXA= +-----END CERTIFICATE----- Index: tags/1.1.4/util/sign/sign.sh =================================================================== --- tags/1.1.4/util/sign/sign.sh (nonexistent) +++ tags/1.1.4/util/sign/sign.sh (revision 818) @@ -0,0 +1,17 @@ +#!/bin/sh + +if test $# -lt 3 +then + echo "Usage: ./sign.sh privkey cert file1 [file2 .. fileN]" +fi + +key="$1" +cert="$2" +shift 2 + +for fn in "$@" +do + openssl dgst -sha256 -sign "$key" -out "$fn.sig" "$fn" + cp "$cert" "$fn.crt" +done + Property changes on: tags/1.1.4/util/sign/sign.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/1.1.4/util/sign/verify.sh =================================================================== --- tags/1.1.4/util/sign/verify.sh (nonexistent) +++ tags/1.1.4/util/sign/verify.sh (revision 818) @@ -0,0 +1,123 @@ +#!/bin/sh + +### defaults ### +ca=rootca_repo.hu_2020.crt +crl=crl_repo.hu.pem + +### implementation ### + +verify() +{ + local base="$1" sig="$1.sig" crt="$1.crt" + + # check if all files are in place + if test ! -f "$base" + then + echo "Content file $base does not exist" >&2 + return 1 + fi + + if test ! -f "$sig" + then + echo "Signature file $sig does not exist - please download that too!" >&2 + return 1 + fi + + if test ! -f "$crt" + then + echo "Certificate file $crt does not exist - please download that too!" >&2 + return 1 + fi + + if test ! -f "$ca" + then + echo "repo.hu CA cert $ca not found. Please download it from multiple sources" >&2 + return 1 + fi + + if test ! -f "$crl" + then + echo "repo.hu CRL $crl not found. Please download it from multiple sources" >&2 + return 1 + fi + + # step 4: check file's cert against repo.hu CA and CRL + cat $ca $crl > .ca_crl.pem + openssl verify -crl_check -CAfile .ca_crl.pem $crt >&2 + if test $? != 0 + then + return 1 + fi + + # step 5: check file's sig against file's cert + openssl x509 -pubkey -noout -in $crt > $crt.pem && \ + openssl dgst -verify $crt.pem -signature $sig $base >&2 +} + +fingerprint() +{ + echo -n "CA " + openssl x509 -fingerprint -noout -in $ca + echo -n "CRL " + openssl crl -fingerprint -noout -in $crl +} + +print_file() +{ + case "$1" in + *.crt) openssl x509 -in "$1" -text ;; + crl*.pem) openssl crl -in "$1" -text ;; + *) echo "Don't know how to print that file" ;; + esac +} + +help() +{ +echo 'verify.sh - pcb-rnd download signature verify script +Usage: ./verify.sh [--fp] [--ca CA_file] [--crl CRL_file] downloaded_file + +Download the CA and CRL files from multiple sources to make sure they match. +Altneratively print the the fingerprint with --fp and check that from +multiple sources. + +The verification process is documented at + +http://www.repo.hu/cgi-bin/pool.cgi?cmd=show&node=sign + +Remember: + + - if you run this for the first time, you absolutely need to verify the CA + from multiple sources + + - before running the script, please get the latest CRL, from multiple sources + +The effective security of this process largely depends on these two steps. +' +} + +### main ### + +bad=0 +while test $# -gt 0 +do + case "$1" in + --help) help "$@"; exit;; + --fp) fingerprint ;; + --ca) shift 1; ca="$1";; + --crl) shift 1; crl="$1";; + --print) shift 1; print_file "$1" ;; + *) + verify "$1" + if test $? = 0 + then + echo "*** $1: ok" + else + echo "*** $1: FAILED" + bad=1 + fi + esac + + shift 1 +done + +exit $bad Property changes on: tags/1.1.4/util/sign/verify.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property